Spaces:
Runtime error
Runtime error
Commit
•
ed88f69
0
Parent(s):
Duplicate from huggan/huggingnft
Browse filesCo-authored-by: Aleksey Korshuk <[email protected]>
- .gitattributes +28 -0
- .streamlit/config.toml +6 -0
- README.md +14 -0
- app.py +301 -0
- requirements.txt +7 -0
.gitattributes
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
*.7z filter=lfs diff=lfs merge=lfs -text
|
2 |
+
*.arrow filter=lfs diff=lfs merge=lfs -text
|
3 |
+
*.bin filter=lfs diff=lfs merge=lfs -text
|
4 |
+
*.bin.* filter=lfs diff=lfs merge=lfs -text
|
5 |
+
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
6 |
+
*.ftz filter=lfs diff=lfs merge=lfs -text
|
7 |
+
*.gz filter=lfs diff=lfs merge=lfs -text
|
8 |
+
*.h5 filter=lfs diff=lfs merge=lfs -text
|
9 |
+
*.joblib filter=lfs diff=lfs merge=lfs -text
|
10 |
+
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
11 |
+
*.model filter=lfs diff=lfs merge=lfs -text
|
12 |
+
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
13 |
+
*.onnx filter=lfs diff=lfs merge=lfs -text
|
14 |
+
*.ot filter=lfs diff=lfs merge=lfs -text
|
15 |
+
*.parquet filter=lfs diff=lfs merge=lfs -text
|
16 |
+
*.pb filter=lfs diff=lfs merge=lfs -text
|
17 |
+
*.pt filter=lfs diff=lfs merge=lfs -text
|
18 |
+
*.pth filter=lfs diff=lfs merge=lfs -text
|
19 |
+
*.rar filter=lfs diff=lfs merge=lfs -text
|
20 |
+
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
21 |
+
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
22 |
+
*.tflite filter=lfs diff=lfs merge=lfs -text
|
23 |
+
*.tgz filter=lfs diff=lfs merge=lfs -text
|
24 |
+
*.wasm filter=lfs diff=lfs merge=lfs -text
|
25 |
+
*.xz filter=lfs diff=lfs merge=lfs -text
|
26 |
+
*.zip filter=lfs diff=lfs merge=lfs -text
|
27 |
+
*.zstandard filter=lfs diff=lfs merge=lfs -text
|
28 |
+
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
.streamlit/config.toml
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[theme]
|
2 |
+
primaryColor = "#d33682"
|
3 |
+
backgroundColor = "#002b36"
|
4 |
+
secondaryBackgroundColor = "#586e75"
|
5 |
+
textColor = "#fafafa"
|
6 |
+
font = "sans serif"
|
README.md
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
---
|
2 |
+
title: Hugging NFT
|
3 |
+
emoji: 🤖
|
4 |
+
colorFrom: indigo
|
5 |
+
colorTo: green
|
6 |
+
sdk: streamlit
|
7 |
+
sdk_version: 1.2.0
|
8 |
+
app_file: app.py
|
9 |
+
pinned: true
|
10 |
+
license: apache-2.0
|
11 |
+
duplicated_from: huggan/huggingnft
|
12 |
+
---
|
13 |
+
|
14 |
+
Check out the configuration reference at https://huggingface.co/docs/hub/spaces#reference
|
app.py
ADDED
@@ -0,0 +1,301 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import json
|
2 |
+
|
3 |
+
import torch
|
4 |
+
|
5 |
+
from huggingnft.lightweight_gan.train import timestamped_filename
|
6 |
+
from streamlit_option_menu import option_menu
|
7 |
+
|
8 |
+
from huggingface_hub import hf_hub_download, file_download
|
9 |
+
from PIL import Image
|
10 |
+
|
11 |
+
from huggingface_hub.hf_api import HfApi
|
12 |
+
import streamlit as st
|
13 |
+
from huggingnft.lightweight_gan.lightweight_gan import Generator, LightweightGAN, evaluate_in_chunks, Trainer
|
14 |
+
from accelerate import Accelerator
|
15 |
+
from huggan.pytorch.cyclegan.modeling_cyclegan import GeneratorResNet
|
16 |
+
from torchvision import transforms as T
|
17 |
+
from torchvision.transforms import Compose, Resize, ToTensor, Normalize, RandomCrop, RandomHorizontalFlip
|
18 |
+
from torchvision.utils import make_grid
|
19 |
+
import requests
|
20 |
+
|
21 |
+
hfapi = HfApi()
|
22 |
+
model_names = [model.modelId[model.modelId.index("/") + 1:] for model in hfapi.list_models(author="huggingnft")]
|
23 |
+
|
24 |
+
# streamlit-option-menu
|
25 |
+
# st.set_page_config(page_title="Streamlit App Gallery", page_icon="", layout="wide")
|
26 |
+
|
27 |
+
# sysmenu = '''
|
28 |
+
# <style>
|
29 |
+
# #MainMenu {visibility:hidden;}
|
30 |
+
# footer {visibility:hidden;}
|
31 |
+
# '''
|
32 |
+
# st.markdown(sysmenu,unsafe_allow_html=True)
|
33 |
+
|
34 |
+
# # Add a logo (optional) in the sidebar
|
35 |
+
# logo = Image.open(r'C:\Users\13525\Desktop\Insights_Bees_logo.png')
|
36 |
+
# profile = Image.open(r'C:\Users\13525\Desktop\medium_profile.png')
|
37 |
+
|
38 |
+
ABOUT_TEXT = "🤗 Hugging NFT - Generate NFT by OpenSea collection name."
|
39 |
+
CONTACT_TEXT = """
|
40 |
+
_Built by Aleksey Korshuk, Christian Cancedda and Hugging Face community with love_ ❤️
|
41 |
+
|
42 |
+
[![Follow](https://img.shields.io/github/followers/AlekseyKorshuk?style=social)](https://github.com/AlekseyKorshuk)
|
43 |
+
[![Follow](https://img.shields.io/twitter/follow/alekseykorshuk?style=social)](https://twitter.com/intent/follow?screen_name=alekseykorshuk)
|
44 |
+
|
45 |
+
[![Follow](https://img.shields.io/github/followers/Chris1nexus?style=social)](https://github.com/Chris1nexus)
|
46 |
+
[![Follow](https://img.shields.io/twitter/follow/chris_cancedda?style=social)](https://twitter.com/intent/follow?screen_name=chris_cancedda)
|
47 |
+
|
48 |
+
|
49 |
+
Star project repository:
|
50 |
+
|
51 |
+
[![GitHub stars](https://img.shields.io/github/stars/AlekseyKorshuk/huggingnft?style=social)](https://github.com/AlekseyKorshuk/huggingnft)
|
52 |
+
|
53 |
+
"""
|
54 |
+
GENERATE_IMAGE_TEXT = "Generate NFT by selecting existing model based on OpenSea collection. You can create new model or imporve existing in few clicks — check [project repository](https://github.com/AlekseyKorshuk/huggingnft)."
|
55 |
+
INTERPOLATION_TEXT = "Generate interpolation between two NFTs by selecting existing model based on OpenSea collection. You can create new model or imporve existing in few clicks — check [project repository](https://github.com/AlekseyKorshuk/huggingnft)."
|
56 |
+
COLLECTION2COLLECTION_TEXT = "Generate first NFT with existing model and transform it to another collection by selecting existing model based on OpenSea collections. You can create new model or imporve existing in few clicks — check [project repository](https://github.com/AlekseyKorshuk/huggingnft)."
|
57 |
+
|
58 |
+
TRAIN_TEXT = "> If you think that the results of the model are not good enough and they can be improved, you can train the model more in a few clicks. If you notice that the model is overtrained, then you can easily return to the best version. Check [project repository](https://github.com/AlekseyKorshuk/huggingnft) to know more about that."
|
59 |
+
|
60 |
+
STOPWORDS = ["-old"]
|
61 |
+
COLLECTION2COLLECTION_KEYS = ["__2__"]
|
62 |
+
|
63 |
+
|
64 |
+
def load_lightweight_model(model_name):
|
65 |
+
file_path = file_download.hf_hub_download(
|
66 |
+
repo_id=model_name,
|
67 |
+
filename="config.json"
|
68 |
+
)
|
69 |
+
config = json.loads(open(file_path).read())
|
70 |
+
organization_name, name = model_name.split("/")
|
71 |
+
model = Trainer(**config, organization_name=organization_name, name=name)
|
72 |
+
model.load(use_cpu=True)
|
73 |
+
model.accelerator = Accelerator()
|
74 |
+
return model
|
75 |
+
|
76 |
+
|
77 |
+
def clean_models(model_names, stopwords):
|
78 |
+
cleaned_model_names = []
|
79 |
+
for model_name in model_names:
|
80 |
+
clear = True
|
81 |
+
for stopword in stopwords:
|
82 |
+
if stopword in model_name:
|
83 |
+
clear = False
|
84 |
+
break
|
85 |
+
if clear:
|
86 |
+
cleaned_model_names.append(model_name)
|
87 |
+
return cleaned_model_names
|
88 |
+
|
89 |
+
def get_concat_h(im1, im2):
|
90 |
+
dst = Image.new('RGB', (im1.width + im2.width, im1.height))
|
91 |
+
dst.paste(im1, (0, 0))
|
92 |
+
dst.paste(im2, (im1.width, 0))
|
93 |
+
return dst
|
94 |
+
|
95 |
+
model_names = clean_models(model_names, STOPWORDS)
|
96 |
+
|
97 |
+
with st.sidebar:
|
98 |
+
choose = option_menu("Hugging NFT",
|
99 |
+
["About", "Generate image", "Interpolation", "Collection2Collection", "Contact"],
|
100 |
+
icons=['house', 'camera fill', 'bi bi-youtube', 'book', 'person lines fill'],
|
101 |
+
menu_icon="app-indicator", default_index=0,
|
102 |
+
styles={
|
103 |
+
# "container": {"padding": "5!important", "background-color": "#fafafa", },
|
104 |
+
"container": {"border-radius": ".0rem"},
|
105 |
+
# "icon": {"color": "orange", "font-size": "25px"},
|
106 |
+
# "nav-link": {"font-size": "16px", "text-align": "left", "margin": "0px",
|
107 |
+
# "--hover-color": "#eee"},
|
108 |
+
# "nav-link-selected": {"background-color": "#02ab21"},
|
109 |
+
}
|
110 |
+
)
|
111 |
+
st.sidebar.markdown(
|
112 |
+
"""
|
113 |
+
<style>
|
114 |
+
.aligncenter {
|
115 |
+
text-align: center;
|
116 |
+
}
|
117 |
+
</style>
|
118 |
+
<p style='text-align: center'>
|
119 |
+
<a href="https://github.com/AlekseyKorshuk/huggingnft" target="_blank">Project Repository</a>
|
120 |
+
</p>
|
121 |
+
<p class="aligncenter">
|
122 |
+
<a href="https://github.com/AlekseyKorshuk/huggingnft" target="_blank">
|
123 |
+
<img src="https://img.shields.io/github/stars/AlekseyKorshuk/huggingnft?style=social"/>
|
124 |
+
</a>
|
125 |
+
</p>
|
126 |
+
<p class="aligncenter">
|
127 |
+
<a href="https://twitter.com/alekseykorshuk" target="_blank">
|
128 |
+
<img src="https://img.shields.io/twitter/follow/alekseykorshuk?style=social"/>
|
129 |
+
</a>
|
130 |
+
</p>
|
131 |
+
|
132 |
+
<p class="aligncenter">
|
133 |
+
<a href="https://twitter.com/chris_cancedda" target="_blank">
|
134 |
+
<img src="https://img.shields.io/twitter/follow/chris_cancedda?style=social"/>
|
135 |
+
</a>
|
136 |
+
</p>
|
137 |
+
|
138 |
+
""",
|
139 |
+
unsafe_allow_html=True,
|
140 |
+
)
|
141 |
+
|
142 |
+
if choose == "About":
|
143 |
+
README = requests.get("https://raw.githubusercontent.com/AlekseyKorshuk/huggingnft/main/README.md").text
|
144 |
+
README = str(README).replace('width="1200"','width="700"')
|
145 |
+
# st.title(choose)
|
146 |
+
st.markdown(README, unsafe_allow_html=True)
|
147 |
+
|
148 |
+
if choose == "Contact":
|
149 |
+
st.title(choose)
|
150 |
+
st.markdown(CONTACT_TEXT)
|
151 |
+
|
152 |
+
if choose == "Generate image":
|
153 |
+
st.title(choose)
|
154 |
+
st.markdown(GENERATE_IMAGE_TEXT)
|
155 |
+
|
156 |
+
model_name = st.selectbox(
|
157 |
+
'Choose model:',
|
158 |
+
clean_models(model_names, COLLECTION2COLLECTION_KEYS)
|
159 |
+
)
|
160 |
+
generation_type = st.selectbox(
|
161 |
+
'Select generation type:',
|
162 |
+
["default", "ema"]
|
163 |
+
)
|
164 |
+
|
165 |
+
nrows = st.number_input("Number of rows:",
|
166 |
+
min_value=1,
|
167 |
+
max_value=10,
|
168 |
+
step=1,
|
169 |
+
value=8,
|
170 |
+
)
|
171 |
+
generate_image_button = st.button("Generate")
|
172 |
+
|
173 |
+
if generate_image_button:
|
174 |
+
with st.spinner(text=f"Downloading selected model..."):
|
175 |
+
model = load_lightweight_model(f"huggingnft/{model_name}")
|
176 |
+
with st.spinner(text=f"Generating..."):
|
177 |
+
image = model.generate_app(
|
178 |
+
num=timestamped_filename(),
|
179 |
+
nrow=nrows,
|
180 |
+
checkpoint=-1,
|
181 |
+
types=generation_type
|
182 |
+
)[0]
|
183 |
+
st.markdown(TRAIN_TEXT)
|
184 |
+
st.image(
|
185 |
+
image
|
186 |
+
)
|
187 |
+
|
188 |
+
if choose == "Interpolation":
|
189 |
+
st.title(choose)
|
190 |
+
st.markdown(INTERPOLATION_TEXT)
|
191 |
+
|
192 |
+
model_name = st.selectbox(
|
193 |
+
'Choose model:',
|
194 |
+
clean_models(model_names, COLLECTION2COLLECTION_KEYS)
|
195 |
+
)
|
196 |
+
nrows = st.number_input("Number of rows:",
|
197 |
+
min_value=1,
|
198 |
+
max_value=4,
|
199 |
+
step=1,
|
200 |
+
value=1,
|
201 |
+
)
|
202 |
+
|
203 |
+
num_steps = st.number_input("Number of steps:",
|
204 |
+
min_value=1,
|
205 |
+
max_value=200,
|
206 |
+
step=1,
|
207 |
+
value=100,
|
208 |
+
)
|
209 |
+
generate_image_button = st.button("Generate")
|
210 |
+
|
211 |
+
if generate_image_button:
|
212 |
+
with st.spinner(text=f"Downloading selected model..."):
|
213 |
+
model = load_lightweight_model(f"huggingnft/{model_name}")
|
214 |
+
my_bar = st.progress(0)
|
215 |
+
result = model.generate_interpolation(
|
216 |
+
num=timestamped_filename(),
|
217 |
+
num_image_tiles=nrows,
|
218 |
+
num_steps=num_steps,
|
219 |
+
save_frames=False,
|
220 |
+
progress_bar=my_bar
|
221 |
+
)
|
222 |
+
my_bar.empty()
|
223 |
+
st.markdown(TRAIN_TEXT)
|
224 |
+
st.image(
|
225 |
+
result
|
226 |
+
)
|
227 |
+
|
228 |
+
if choose == "Collection2Collection":
|
229 |
+
st.title(choose)
|
230 |
+
st.markdown(COLLECTION2COLLECTION_TEXT)
|
231 |
+
|
232 |
+
model_name = st.selectbox(
|
233 |
+
'Choose model:',
|
234 |
+
set(model_names) - set(clean_models(model_names, COLLECTION2COLLECTION_KEYS))
|
235 |
+
)
|
236 |
+
nrows = st.number_input("Number of images to generate:",
|
237 |
+
min_value=1,
|
238 |
+
max_value=10,
|
239 |
+
step=1,
|
240 |
+
value=1,
|
241 |
+
)
|
242 |
+
generate_image_button = st.button("Generate")
|
243 |
+
|
244 |
+
if generate_image_button:
|
245 |
+
n_channels = 3
|
246 |
+
|
247 |
+
image_size = 256
|
248 |
+
|
249 |
+
input_shape = (image_size, image_size)
|
250 |
+
|
251 |
+
transform = Compose([
|
252 |
+
T.ToPILImage(),
|
253 |
+
T.Resize(input_shape),
|
254 |
+
ToTensor(),
|
255 |
+
Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),
|
256 |
+
])
|
257 |
+
|
258 |
+
with st.spinner(text=f"Downloading selected model..."):
|
259 |
+
translator = GeneratorResNet.from_pretrained(f'huggingnft/{model_name}',
|
260 |
+
input_shape=(n_channels, image_size, image_size),
|
261 |
+
num_residual_blocks=9)
|
262 |
+
|
263 |
+
z = torch.randn(nrows, 100, 1, 1)
|
264 |
+
|
265 |
+
with st.spinner(text=f"Downloading selected model..."):
|
266 |
+
model = load_lightweight_model(f"huggingnft/{model_name.split('__2__')[0]}")
|
267 |
+
|
268 |
+
with st.spinner(text=f"Generating input images..."):
|
269 |
+
punks = model.generate_app(
|
270 |
+
num=timestamped_filename(),
|
271 |
+
nrow=nrows,
|
272 |
+
checkpoint=-1,
|
273 |
+
types="default"
|
274 |
+
)[1]
|
275 |
+
|
276 |
+
pipe_transform = T.Resize((256, 256))
|
277 |
+
|
278 |
+
input = pipe_transform(punks)
|
279 |
+
|
280 |
+
with st.spinner(text=f"Generating output images..."):
|
281 |
+
output = translator(input)
|
282 |
+
|
283 |
+
out_img = make_grid(output,
|
284 |
+
nrow=4, normalize=True)
|
285 |
+
|
286 |
+
# out_img = make_grid(punks,
|
287 |
+
# nrow=8, normalize=True)
|
288 |
+
|
289 |
+
out_transform = Compose([
|
290 |
+
T.ToPILImage()
|
291 |
+
])
|
292 |
+
|
293 |
+
results = []
|
294 |
+
|
295 |
+
for out_punk, out_ape in zip(input, output):
|
296 |
+
results.append(
|
297 |
+
get_concat_h(out_transform(make_grid(out_punk, nrow=1, normalize=True)), out_transform(make_grid(out_ape, nrow=1, normalize=True)))
|
298 |
+
)
|
299 |
+
st.markdown(TRAIN_TEXT)
|
300 |
+
for result in results:
|
301 |
+
st.image(result)
|
requirements.txt
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
streamlit
|
2 |
+
torch
|
3 |
+
torchvision
|
4 |
+
einops
|
5 |
+
streamlit-option-menu
|
6 |
+
git+https://github.com/AlekseyKorshuk/huggingnft
|
7 |
+
git+https://github.com/huggingface/community-events@main
|