2ch commited on
Commit
64ae76b
·
verified ·
1 Parent(s): 1058a5c

Upload искусство_быть_опущенным.ipynb

Browse files
искусство_быть_опущенным.ipynb ADDED
@@ -0,0 +1,248 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "nbformat": 4,
3
+ "nbformat_minor": 0,
4
+ "metadata": {
5
+ "colab": {
6
+ "provenance": [],
7
+ "gpuType": "T4"
8
+ },
9
+ "kernelspec": {
10
+ "name": "python3",
11
+ "display_name": "Python 3"
12
+ },
13
+ "language_info": {
14
+ "name": "python"
15
+ },
16
+ "accelerator": "GPU"
17
+ },
18
+ "cells": [
19
+ {
20
+ "cell_type": "markdown",
21
+ "source": [
22
+ "### 1. ⚠️ подключить гуглодиск на панели слева"
23
+ ],
24
+ "metadata": {
25
+ "id": "7FWvC7H5xcYm"
26
+ }
27
+ },
28
+ {
29
+ "cell_type": "code",
30
+ "execution_count": null,
31
+ "metadata": {
32
+ "cellView": "form",
33
+ "id": "AXREDL496gE-"
34
+ },
35
+ "outputs": [],
36
+ "source": [
37
+ "# @title 2. установить\n",
38
+ "from urllib.parse import urlparse, unquote\n",
39
+ "from tarfile import open as open_tar\n",
40
+ "from pathlib import Path\n",
41
+ "from zstandard import ZstdDecompressor\n",
42
+ "from tqdm import tqdm\n",
43
+ "from json import dumps, loads\n",
44
+ "\n",
45
+ "webui_type = \"a1111\" # @param [\"a1111\",\"sdnext\",\"forge\",\"reforge\",\"comfy\"]\n",
46
+ "commnit_hash = \"\" # @param {\"type\":\"string\"}\n",
47
+ "base_url = 'https://huggingface.co/2ch/repos/resolve/main'\n",
48
+ "ui_url = f'{base_url}/{{ui}}.tar.zst'\n",
49
+ "venv_url = f'{base_url}/{{ui}}_venv.tar.zst'\n",
50
+ "output = Path('/content/drive/MyDrive/work/outputs')\n",
51
+ "output.mkdir(parents=True, exist_ok=True)\n",
52
+ "\n",
53
+ "%cd /content/\n",
54
+ "\n",
55
+ "get_ipython().system('mount -o remount,size=11G /dev/shm')\n",
56
+ "\n",
57
+ "\n",
58
+ "def decompress(input_file, output_dir):\n",
59
+ " output_path = Path(output_dir).resolve()\n",
60
+ " output_path.mkdir(parents=True, exist_ok=True)\n",
61
+ " with open(input_file, 'rb') as source:\n",
62
+ " with ZstdDecompressor().stream_reader(source) as reader:\n",
63
+ " with open_tar(mode='r|', fileobj=reader) as tar:\n",
64
+ " pbar = tqdm(desc='распаковка', unit=' файлов')\n",
65
+ " member = tar.next()\n",
66
+ " while member is not None:\n",
67
+ " if member.isfile():\n",
68
+ " try:\n",
69
+ " target_path = output_path / member.name\n",
70
+ " target_path = target_path.resolve()\n",
71
+ " if not target_path.is_relative_to(output_path):\n",
72
+ " raise ValueError(f'попытка извлечения за пределы целевого каталога: {member.name}')\n",
73
+ " target_path.parent.mkdir(parents=True, exist_ok=True)\n",
74
+ " pbar.set_description(f'распаковано: ...{member.name[30:]}')\n",
75
+ " tar.extract(member, output_path)\n",
76
+ " pbar.update(1)\n",
77
+ " except Exception as e:\n",
78
+ " pbar.write(f'ошибка распаковки {member.name}: {e}')\n",
79
+ " member = tar.next()\n",
80
+ " pbar.close()\n",
81
+ "\n",
82
+ "\n",
83
+ "\n",
84
+ "def dl_unpack(ui):\n",
85
+ " get_ipython().system('rm -rf /dev/shm/*')\n",
86
+ " for url in [venv_url.format(ui=ui), ui_url.format(ui=ui)]:\n",
87
+ " get_ipython().system(f'wget -nv -t 10 --show-progress -q --content-disposition {url} -P /dev/shm')\n",
88
+ " file = Path(unquote(urlparse(url).path))\n",
89
+ " archive, folder = Path('/dev/shm') / file.name, Path('/content')\n",
90
+ " webui_folder = folder / Path(file.stem).stem\n",
91
+ " decompress(archive, folder)\n",
92
+ " get_ipython().system('rm -rf /dev/shm/*')\n",
93
+ " if commnit_hash:\n",
94
+ " get_ipython().system(f'git -C {webui_folder.as_posix} restore .')\n",
95
+ " get_ipython().system(f'git -C {webui_folder.as_posix} checkout {commnit_hash}')\n",
96
+ " if webui_type != 'comfy':\n",
97
+ " get_ipython().system(f'git clone https://huggingface.co/prolapse/dl_models_addon {webui_folder / \"extensions\" / \"dl_models\"}')\n",
98
+ "\n",
99
+ "\n",
100
+ "def output_config():\n",
101
+ " config_json_path = Path(f'/content/{webui_type}') / 'config.json'\n",
102
+ " if not config_json_path.exists():\n",
103
+ " config_json_path.touch()\n",
104
+ " default_outdirs = {\n",
105
+ " 'outdir_samples': '',\n",
106
+ " 'outdir_txt2img_samples': (output / 't2i').as_posix(),\n",
107
+ " 'outdir_img2img_samples': (output / 'i2i').as_posix(),\n",
108
+ " 'outdir_extras_samples': (output / 'upscaled_face_restored').as_posix(),\n",
109
+ " 'outdir_grids': '',\n",
110
+ " 'outdir_txt2img_grids': (output / 't2i_tiles').as_posix(),\n",
111
+ " 'outdir_img2img_grids': (output / 'i2i_tiles').as_posix(),\n",
112
+ " 'outdir_save': (output / 'selected').as_posix(),\n",
113
+ " 'outdir_init_images': (output / 'init-images').as_posix(),\n",
114
+ " }\n",
115
+ " config_json_path.write_text(dumps(default_outdirs, indent=4), encoding='utf-8')\n",
116
+ "\n",
117
+ "\n",
118
+ "dl_unpack(webui_type)\n",
119
+ "\n",
120
+ "if webui_type != 'comfy':\n",
121
+ " from json import dumps, loads\n",
122
+ " output_config()\n",
123
+ "\n",
124
+ "\n"
125
+ ]
126
+ },
127
+ {
128
+ "cell_type": "code",
129
+ "source": [
130
+ "# @title 3. запустить\n",
131
+ "\n",
132
+ "from pathlib import Path\n",
133
+ "from random import randint\n",
134
+ "from subprocess import PIPE, Popen, STDOUT, run\n",
135
+ "from time import sleep\n",
136
+ "from re import compile\n",
137
+ "from requests import get\n",
138
+ "\n",
139
+ "webui_type = \"a1111\" # @param [\"a1111\",\"sdnext\",\"forge\",\"reforge\",\"comfy\"]\n",
140
+ "\n",
141
+ "output = Path('/content/drive/MyDrive/work/outputs')\n",
142
+ "port = randint(7877, 8077)\n",
143
+ "work_dir = f'/content/{webui_type}'\n",
144
+ "python = f'/content/{webui_type}_venv/bin/python'\n",
145
+ "\n",
146
+ "\n",
147
+ "def create_gradio_tunnel(port: int) -> str:\n",
148
+ " gradio_bin = Path('/content/.config/frpc_linux_amd64')\n",
149
+ " bin_url = 'https://cdn-media.huggingface.co/frpc-gradio-0.1/frpc_linux_amd64'\n",
150
+ " max_attempts = 3\n",
151
+ "\n",
152
+ " for attempt in range(max_attempts):\n",
153
+ " try:\n",
154
+ " if not gradio_bin.exists():\n",
155
+ " gradio_bin.parent.mkdir(parents=True, exist_ok=True)\n",
156
+ " response = get(bin_url)\n",
157
+ " response.raise_for_status()\n",
158
+ " gradio_bin.write_bytes(response.content)\n",
159
+ " gradio_bin.chmod(0o777)\n",
160
+ "\n",
161
+ " run(['pkill', '-f', gradio_bin.name], capture_output=True)\n",
162
+ "\n",
163
+ " resp = get('https://api.gradio.app/v2/tunnel-request').json()\n",
164
+ " host, r_port = resp[0]['host'], resp[0]['port']\n",
165
+ "\n",
166
+ " cmd = [\n",
167
+ " str(gradio_bin), 'http',\n",
168
+ " '-n', 'random',\n",
169
+ " '-l', str(port),\n",
170
+ " '-i', '127.0.0.1',\n",
171
+ " '--server_addr', f'{host}:{r_port}',\n",
172
+ " '--uc', '--sd', 'random', '--ue', '--disable_log_color'\n",
173
+ " ]\n",
174
+ " process = Popen(\n",
175
+ " cmd,\n",
176
+ " stdout=PIPE,\n",
177
+ " stderr=STDOUT,\n",
178
+ " text=True\n",
179
+ " )\n",
180
+ "\n",
181
+ " url_pattern = compile(r'https://\\S+')\n",
182
+ " for _ in range(5):\n",
183
+ " line = process.stdout.readline()\n",
184
+ " if match := url_pattern.search(line):\n",
185
+ " return match.group()\n",
186
+ "\n",
187
+ " if process.poll() is not None:\n",
188
+ " break\n",
189
+ "\n",
190
+ " raise RuntimeError('url не найден в выводе')\n",
191
+ "\n",
192
+ " except Exception as e:\n",
193
+ " if attempt == max_attempts - 1:\n",
194
+ " raise RuntimeError(f'не удалось создать туннель после {max_attempts} попыток: {str(e)}')\n",
195
+ "\n",
196
+ " print(f'ошибка (попытка {attempt + 1}): {str(e)}')\n",
197
+ " sleep(2)\n",
198
+ "\n",
199
+ " return ''\n",
200
+ "\n",
201
+ "\n",
202
+ "\n",
203
+ "%cd $work_dir\n",
204
+ "\n",
205
+ "gradio_args = [\n",
206
+ " '--opt-sdp-attention',\n",
207
+ " '--no-half-vae',\n",
208
+ " '--api',\n",
209
+ " '--no-download-sd-model',\n",
210
+ " '--disable-console-progressbars',\n",
211
+ " '--no-hashing',\n",
212
+ " '--skip-version-check',\n",
213
+ " '--skip-python-version-check',\n",
214
+ " '--skip-torch-cuda-test',\n",
215
+ " '--disable-safe-unpickle',\n",
216
+ " '--enable-insecure-extension-access',\n",
217
+ " f'--port {port}',\n",
218
+ " '--listen',\n",
219
+ " '--theme dark',\n",
220
+ " '--no-gradio-queue'\n",
221
+ "]\n",
222
+ "\n",
223
+ "comfy_args = [\n",
224
+ " '--listen 0.0.0.0',\n",
225
+ " f'--port {port}',\n",
226
+ " f'--output-directory {output / \"cozy\"}',\n",
227
+ " '--disable-auto-launch',\n",
228
+ " '--dont-print-server',\n",
229
+ " '--fp8_e4m3fn-unet --fp8_e4m3fn-text-enc', # для флюкс, сд3, т.п.\n",
230
+ " '--use-pytorch-cross-attention --disable-xformers',\n",
231
+ " '--lowvram'\n",
232
+ "]\n",
233
+ "\n",
234
+ "\n",
235
+ "url = create_gradio_tunnel(port)\n",
236
+ "args = ' '.join(comfy_args if webui_type == 'comfy' else gradio_args)\n",
237
+ "print(url)\n",
238
+ "get_ipython().system(f'{python} launch.py {args}')\n"
239
+ ],
240
+ "metadata": {
241
+ "cellView": "form",
242
+ "id": "1kUYNYTMTXNb"
243
+ },
244
+ "execution_count": null,
245
+ "outputs": []
246
+ }
247
+ ]
248
+ }