123
#1
by Grooose - opened
- .gitattributes +0 -1
- README.md +0 -7
- kaggle-util.ipynb +0 -1
- lite-start.ipynb +0 -1
- sdwui-before-new.ipynb +0 -1
- sdwui-before.ipynb +1 -1
- sdwui-start-new.ipynb +0 -1
- sdwui-start-util.dev.ipynb +0 -1737
- sdwui-start-util.ipynb +0 -1735
- sdwui-start-util.mini.ipynb +0 -1652
- sdwui-start.ipynb +1 -1
- sdwui_install.py +0 -734
- stable-diffusion-webui-novelai-sdxl.ipynb +0 -1
- stable-diffusion-webui-novelai.ipynb +0 -1
- venv.zip +3 -0
.gitattributes
CHANGED
|
@@ -33,4 +33,3 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
-
frpc filter=lfs diff=lfs merge=lfs -text
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
README.md
CHANGED
|
@@ -1,10 +1,3 @@
|
|
| 1 |
---
|
| 2 |
license: unknown
|
| 3 |
---
|
| 4 |
-
这是一个在linux jupyter环境便捷启动[stable-diffusion-webui](https://github.com/AUTOMATIC1111/stable-diffusion-webui)的jupyter笔记
|
| 5 |
-
|
| 6 |
-
如果你需要使用,只需要下载 [sdwui-before-new.ipynb](https://huggingface.co/viyi/sdwui/resolve/main/sdwui-before-new.ipynb) 就行
|
| 7 |
-
|
| 8 |
-
主要逻辑都在 sdwui-start-new.ipynb 文件内,一般情况下有功能更新或修复bug都在这个文件,而sdwui-before-new.ipynb这个文件每次都会下载最新的sdwui-start-new.ipynb进行启动
|
| 9 |
-
|
| 10 |
-
现在只有 sdwui-start-util.ipynb 文件还在更新,用于kaggle平台的这个笔记 [stable-diffusion-webui & ComfyUI](https://www.kaggle.com/code/yiyiooo/stable-diffusion-webui-comfyui)
|
|
|
|
| 1 |
---
|
| 2 |
license: unknown
|
| 3 |
---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
kaggle-util.ipynb
DELETED
|
@@ -1 +0,0 @@
|
|
| 1 |
-
{"cells":[{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":[]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["from pathlib import Path\n","import os\n","import time\n","import re\n","import subprocess\n","import threading\n","import sys\n","import socket\n","import torch\n","from typing import List\n","import uuid"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["# 内置参数默认值,当上下文有参数时可覆盖默认值\n","_runing = False\n","_useFrpc = locals().get('useFrpc') or globals().get('useFrpc') or True\n","\n","_useNgrok = locals().get('useNgrok') or globals().get('useNgrok') or True\n","\n","_server_port = locals().get('server_port') or globals().get('server_port') or 7860\n"," \n","_huggingface_token = locals().get('huggingface_token') or globals().get('huggingface_token') or '{input_path}/configs/huggingface_token.txt'\n","_huggingface_token = _huggingface_token\\\n"," .replace('{sdwui}','stable-diffusion-webui')\\\n"," .replace('{wui}',\"webui\")\n","\n","show_shell_info = locals().get('hidden_console_info') or globals().get('hidden_console_info')\n","if show_shell_info is None: show_shell_info = False\n","\n","run_by_none_device = False\n","\n","_proxy_path = locals().get('proxy_path') or globals().get('proxy_path') or {}\n","\n","_config_args:dict[str, str] = locals().get('config_args') or globals().get('config_args') or {}"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["\n","def run(command, cwd=None, desc=None, errdesc=None, custom_env=None,try_error:bool=True) -> str:\n"," global show_shell_info\n"," if desc is not None:\n"," print(desc)\n","\n"," run_kwargs = {\n"," \"args\": command,\n"," \"shell\": True,\n"," \"cwd\": cwd,\n"," \"env\": os.environ if custom_env is None else custom_env,\n"," \"encoding\": 'utf8',\n"," \"errors\": 'ignore',\n"," }\n","\n"," if not show_shell_info:\n"," run_kwargs[\"stdout\"] = run_kwargs[\"stderr\"] = subprocess.PIPE\n","\n"," result = subprocess.run(**run_kwargs)\n","\n"," if result.returncode != 0:\n"," error_bits = [\n"," f\"{errdesc or 'Error running command'}.\",\n"," f\"Command: {command}\",\n"," f\"Error code: {result.returncode}\",\n"," ]\n"," if result.stdout:\n"," error_bits.append(f\"stdout: {result.stdout}\")\n"," if result.stderr:\n"," error_bits.append(f\"stderr: {result.stderr}\")\n"," if try_error:\n"," print((RuntimeError(\"\\n\".join(error_bits))))\n"," else:\n"," raise RuntimeError(\"\\n\".join(error_bits))\n","\n"," if show_shell_info:\n"," print((result.stdout or \"\"))\n"," return (result.stdout or \"\")\n","\n","def mkdirs(path, exist_ok=True):\n"," if path and not Path(path).exists():\n"," os.makedirs(path,exist_ok=exist_ok)\n","\n","\n","# 检查网络\n","def check_service(host, port):\n"," try:\n"," socket.create_connection((host, port), timeout=5)\n"," return True\n"," except socket.error:\n"," return False\n","\n","\n","# 检查gpu是否存在\n","def check_gpu():\n"," if not run_by_none_device and torch.cuda.device_count() == 0:\n"," raise Exception('当前环境没有GPU')\n","\n","\n","def echoToFile(content:str,path:str):\n"," if path.find('/') >= 0:\n"," _path = '/'.join(path.split('/')[:-1])\n"," run(f'''mkdir -p {_path}''')\n"," with open(path,'w') as sh:\n"," sh.write(content)\n"," \n","def get_freefrp_confog(local_port):\n"," rd_str = uuid.uuid1()\n"," return (f'''\n","[common]\n","server_addr = frp.freefrp.net\n","server_port = 7000\n","token = freefrp.net\n","\n","[{rd_str}_http]\n","type = http\n","local_ip = 127.0.0.1\n","local_port = {local_port}\n","custom_domains = {rd_str}.frp.eaias.com\n","''',f'http://{rd_str}.frp.eaias.com')"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["\n","_install_path = f\"{os.environ['HOME']}/sd_webui\" # 安装目录\n","_output_path = '/kaggle/working' if os.path.exists('/kaggle/working/') else f\"{os.environ['HOME']}/.sdwui/Output\" # 输出目录 如果使用google云盘 会在google云盘增加sdwebui/Output\n","_input_path = '/kaggle/input' # 输入目录\n","_ui_dir_name = 'sd_main_dir'\n","\n","_install_path = locals().get('install_path') or globals().get('install_path') or _install_path\n","_output_path = locals().get('output_path') or globals().get('output_path') or _output_path\n","_input_path = locals().get('input_path') or globals().get('input_path') or _input_path\n","_ui_dir_name = locals().get('ui_dir_name') or globals().get('ui_dir_name') or _ui_dir_name\n","\n","install_path = _install_path\n","output_path = _output_path\n","input_path = _input_path\n","ui_dir_name = _ui_dir_name\n"," \n","google_drive = '' \n","\n","\n","_useGooglrDrive = locals().get('useGooglrDrive') or globals().get('useGooglrDrive') or True\n","\n","# 连接谷歌云\n","try:\n"," if _useGooglrDrive:\n"," from google.colab import drive\n"," drive.mount(f'~/google_drive')\n"," google_drive = f\"{os.environ['HOME']}/google_drive/MyDrive\"\n"," _output_path = f'{google_drive}/sdwebui/Output'\n"," _input_path = f'{google_drive}/sdwebui/Input'\n"," run(f'''mkdir -p {_input_path}''')\n"," print('''\n","已经链接到谷歌云盘\n","已在云盘创建Input和Output目录\n"," ''')\n","except:\n"," _useGooglrDrive = False\n","\n","run(f'''mkdir -p {_install_path}''')\n","run(f'''mkdir -p {_output_path}''')\n","\n","\n","os.environ['install_path'] = _install_path\n","os.environ['output_path'] = _output_path\n","os.environ['google_drive'] = google_drive\n","os.environ['input_path'] = _input_path\n","\n","def replace_path(input_str:str):\n"," if not input_str: return ''\n"," for key in _config_args:\n"," input_str = input_str.replace(key,_config_args[key])\n"," \n"," return input_str.replace('$install_path',_install_path)\\\n"," .replace('{install_path}',_install_path)\\\n"," .replace('$input_path',_input_path)\\\n"," .replace('{input_path}',_input_path)\\\n"," .replace('$output_path',_output_path)\\\n"," .replace('{output_path}',_output_path)\\\n"," .replace('{sdwui}','stable-diffusion-webui')\\\n"," .replace('{wui}',\"webui\")\n","\n","space_string = ' \\n\\r\\t\\'\\\",'\n","\n","def config_reader(conf:str):\n"," args = [replace_path(item.split('#')[0].strip(space_string)) for item in conf.split('\\n') if item.strip(space_string)]\n"," return [item.strip() for item in args if item.strip()]\n"]},{"cell_type":"code","execution_count":null,"metadata":{"_kg_hide-input":true,"id":"i3LhnwYHLCtC","trusted":true},"outputs":[],"source":["ngrokTokenFile = os.path.join(_input_path,'configs/ngrok_token.txt') # 非必填 存放ngrokToken的文件的路径\n","frpcConfigFile = os.path.join(_input_path,'configs/frpc_koishi.ini') # 非必填 frp 配置文件\n","# ss证书目录 下载nginx的版本,把pem格式改成crt格式\n","frpcSSLFFlies = [os.path.join(_input_path,'configs/koishi_ssl')]\n","if 'frp_ssl_dir' in locals() or 'frp_ssl_dir' in globals():\n"," frpcSSLFFlies = frpcSSLFFlies + config_reader(locals().get('frp_ssl_dir') or globals().get('frp_ssl_dir'))\n","# frpc 文件目录 如果目录不存在,会自动下载,也可以在数据集搜索 viyiviyi/utils 添加\n","frpcExePath = os.path.join(_input_path,'utils-tools/frpc')\n","# 其他需要加载的webui启动参数 写到【参数列表】这个配置去\n","\n","# 用于使用kaggle api的token文件 参考 https://www.kaggle.com/docs/api\n","# 此文件用于自动上传koishi的相关配置 也可以用于保存重要的输出文件\n","kaggleApiTokenFile = locals().get('kaggle_api_token') or globals().get('kaggle_api_token') or os.path.join(_input_path,'configs/kaggle.json')\n","\n","requirements = []\n"]},{"cell_type":"code","execution_count":null,"metadata":{"_kg_hide-input":true,"id":"a_GtG2ayLCtD","trusted":true},"outputs":[],"source":["# 这下面的是用于初始化一些值或者环境变量的,轻易别改\n","_setting_file = replace_path(locals().get('setting_file') or globals().get('setting_file') or '/kaggle/working/configs/config.json')\n","\n","_ui_config_file = replace_path(locals().get('ui_config_file') or globals().get('ui_config_file') or '/kaggle/working/configs/ui-config.json')\n","\n","# 设置文件路径\n","if Path(f\"{os.environ['HOME']}/google_drive/MyDrive\").exists():\n"," if _setting_file == '/kaggle/working/configs/config.json':\n"," _setting_file = os.path.join(_output_path,'configs/config.json')\n"," if _ui_config_file == '/kaggle/working/configs/ui-config.json':\n"," _ui_config_file = os.path.join(_output_path,'configs/ui-config.json')\n"," \n","frpcStartArg = ''\n","freefrp_url = ''\n","_frp_temp_config_file = ''\n","_frp_config_or_file = replace_path(locals().get('frp_config_or_file') or globals().get('frp_config_or_file')) or frpcConfigFile\n","run(f'''mkdir -p {_install_path}/configFiles''')\n","if _frp_config_or_file:\n"," if '[common]' in _frp_config_or_file:\n"," echoToFile(_frp_config_or_file,f'{_install_path}/configFiles/temp_frpc_webui.ini')\n"," _frp_temp_config_file = f'{_install_path}/configFiles/temp_frpc_webui.ini'\n"," elif '.ini' in _frp_config_or_file:\n"," _frp_temp_config_file = _frp_config_or_file.strip()\n"," \n"," if _frp_temp_config_file:\n"," if Path(_frp_temp_config_file).exists():\n"," run(f'''cp -f {_frp_temp_config_file} {_install_path}/configFiles/frpc_webui.ini''')\n"," run(f'''sed -i \"s/local_port = .*/local_port = {_server_port}/g\" {_install_path}/configFiles/frpc_webui.ini''')\n"," frpcStartArg = f' -c {_install_path}/configFiles/frpc_webui.ini'\n"," elif _frp_config_or_file.strip().startswith('-f'):\n"," frpcStartArg = _frp_config_or_file.strip()\n"," \n","if not frpcStartArg:\n"," conf,url = get_freefrp_confog(_server_port)\n"," echoToFile(conf,f'{_install_path}/configFiles/frpc_webui.ini')\n"," freefrp_url = url\n"," frpcStartArg = f' -c {_install_path}/configFiles/frpc_webui.ini'\n","\n","ngrokToken=''\n","_ngrok_config_or_file = replace_path(locals().get('ngrok_config_or_file') or globals().get('ngrok_config_or_file')) or ngrokTokenFile\n","if _ngrok_config_or_file:\n"," if Path(_ngrok_config_or_file.strip()).exists():\n"," ngrokTokenFile = _ngrok_config_or_file.strip()\n"," if Path(ngrokTokenFile).exists():\n"," with open(ngrokTokenFile,encoding = \"utf-8\") as nkfile:\n"," ngrokToken = nkfile.readline()\n"," elif not _ngrok_config_or_file.strip().startswith('/'):\n"," ngrokToken=_ngrok_config_or_file.strip()\n"," \n","huggingface_headers:dict = None "]},{"cell_type":"markdown","metadata":{},"source":["## 文件下载工具\n","\n","---\n","\n","link_or_download_flie(config:str, skip_url:bool=False, _link_instead_of_copy:bool=True, base_path:str = '',sync:bool=False,thread_num:int=None)"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["import concurrent.futures\n","import importlib\n","import os\n","import pprint\n","import re\n","from pathlib import Path\n","from typing import List\n","\n","import requests\n","\n","show_shell_info = False\n","\n","def is_installed(package):\n"," try:\n"," spec = importlib.util.find_spec(package)\n"," except ModuleNotFoundError:\n"," return False\n","\n"," return spec is not None\n","\n","def download_file(url:str, filename:str, dist_path:str, cache_path = '',_link_instead_of_copy:bool=True,headers={}):\n"," # 获取文件的真实文件名\n"," if not filename:\n"," with requests.get(url, stream=True,headers=headers) as r:\n"," if 'Content-Disposition' in r.headers:\n"," filename = r.headers['Content-Disposition'].split('filename=')[1].strip('\"')\n"," r.close()\n"," if not filename and re.search(r'/[^/]+\\.[^/]+$',url):\n"," filename = url.split('/')[-1].split('?')[0]\n"," \n"," filename = re.sub(r'[\\\\/:*?\"<>|;]', '', filename)\n"," filename = re.sub(r'[\\s\\t]+', '_', filename)\n"," \n"," print(f'下载 {filename} url: {url} --> {dist_path}')\n"," \n"," # 创建目录\n"," if cache_path and not Path(cache_path).exists():\n"," os.makedirs(cache_path,exist_ok=True)\n"," if dist_path and not Path(dist_path).exists():\n"," os.makedirs(dist_path,exist_ok=True)\n"," \n"," # 拼接文件的完整路径\n"," filepath = os.path.join(dist_path, filename)\n","\n"," if cache_path:\n"," cache_path = os.path.join(cache_path, filename)\n"," \n"," # 判断文件是否已存在\n"," if Path(filepath).exists():\n"," print(f'文件 {filename} 已存在 {dist_path}')\n"," return\n"," \n"," if cache_path and Path(cache_path).exists():\n"," run(f'cp -n -r -f {\"-s\" if _link_instead_of_copy else \"\"} {cache_path} {dist_path}')\n"," print(f'文件缓存 {cache_path} --> {dist_path}')\n"," return\n"," # 下载文件\n"," with requests.get(url, stream=True, headers=headers) as r:\n"," r.raise_for_status()\n"," with open(cache_path or filepath, 'wb') as f:\n"," for chunk in r.iter_content(chunk_size=1024):\n"," if chunk:\n"," f.write(chunk)\n"," # 如果使用了缓存目录 需要复制或链接文件到目标目录\n"," if cache_path:\n"," run(f'cp -n -r -f {\"-s\" if _link_instead_of_copy else \"\"} {cache_path} {dist_path}')\n"," print(f'下载完成 {filename} --> {dist_path}')\n"," \n","def download_git(url, dist_path, cache_path = '',_link_instead_of_copy:bool=True):\n"," if not Path(dist_path).exists():\n"," os.makedirs(dist_path,exist_ok=True)\n"," if show_shell_info:\n"," print(f'git 下载 {url} --> {dist_path}')\n"," if cache_path and not Path(cache_path).exists():\n"," os.makedirs(cache_path,exist_ok=True)\n"," run(f'git clone {url}',cwd = cache_path)\n"," if cache_path:\n"," run(f'cp -n -r -f {cache_path}/* {dist_path}')\n"," else:\n"," run(f'git clone {url}',cwd = dist_path)\n"," if show_shell_info:\n"," print(f'git 下载完成 {url} --> {dist_path}')\n"," \n"," \n","def download_huggingface(url:str, filename:str, dist_path, cache_path = '',_link_instead_of_copy:bool=True):\n"," fileReg = r'^https:\\/\\/huggingface.co(\\/([^\\/]+\\/)?[^\\/]+\\/[^\\/]+\\/(resolve|blob)\\/[^\\/]+\\/|[^\\.]+\\.[^\\.]+$|download=true)'\n"," def isFile(url:str):\n"," if re.match(fileReg,url):\n"," return True\n"," return False\n"," if isFile(url):\n"," download_file(url,filename,dist_path,cache_path,_link_instead_of_copy,headers=huggingface_headers)\n"," else:\n"," download_git(url,dist_path,cache_path,_link_instead_of_copy)\n"," \n","# 加入文件到下载列表\n","def pause_url(url:str,dist_path:str):\n"," file_name = ''\n"," if re.match(r'^[^:]+:(https?|ftps?)://', url, flags=0):\n"," file_name = re.findall(r'^[^:]+:',url)[0][:-1]\n"," url = url[len(file_name)+1:]\n"," if not re.match(r'^(https?|ftps?)://',url):\n"," return\n"," file_name = re.sub(r'\\s+','_',file_name or '')\n"," path_hash = str(hash(url)).replace('-','')\n"," \n"," return {'file_name':file_name,'path_hash':path_hash,'url':url,'dist_path':dist_path}\n","\n","def download_urls(download_list:List[dict],sync:bool=False,thread_num:int=5, \n"," cache_path:str=os.path.join(os.environ['HOME'],'.cache','download_util'),\n"," _link_instead_of_copy:bool=True,is_await:bool=False):\n"," if sync:\n"," for conf in download_list:\n"," cache_dir = os.path.join(cache_path,conf['path_hash'])\n"," if conf['url'].startswith('https://github.com'):\n"," download_git(conf['url'],conf['dist_path'],cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy)\n"," continue\n"," if conf['url'].startswith('https://huggingface.co'):\n"," download_huggingface(conf['url'],conf['file_name'],conf['dist_path'],cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy)\n"," continue\n"," if conf['url'].startswith('https://civitai.com'):\n"," if not re.search(r'token=.+', conf['url']):\n"," if conf['url'].find('?') == -1:\n"," conf['url'] = conf['url']+'?token=fee8bb78b75566eddfd04d061996185c'\n"," else:\n"," conf['url'] = conf['url']+'&token=fee8bb78b75566eddfd04d061996185c'\n"," download_file(conf['url'],conf['file_name'],conf['dist_path'],cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy)\n"," else:\n"," executor = concurrent.futures.ThreadPoolExecutor(max_workers=thread_num)\n"," futures = []\n"," for conf in download_list:\n"," cache_dir = os.path.join(cache_path,conf['path_hash'])\n"," if conf['url'].startswith('https://github.com'):\n"," futures.append(executor.submit(download_git, conf['url'],conf['dist_path'],\n"," cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy))\n"," continue\n"," if conf['url'].startswith('https://huggingface.co'):\n"," futures.append(executor.submit(download_huggingface,conf['url'],conf['file_name'],conf['dist_path'],cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy))\n"," continue\n"," if conf['url'].startswith('https://civitai.com'):\n"," if not re.search(r'token=.+', conf['url']):\n"," if conf['url'].find('?') == -1:\n"," conf['url'] = conf['url']+'?token=fee8bb78b75566eddfd04d061996185c'\n"," else:\n"," conf['url'] = conf['url']+'&token=fee8bb78b75566eddfd04d061996185c'\n"," futures.append(executor.submit(download_file, conf['url'],conf['file_name'],conf['dist_path'],\n"," cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy))\n"," if is_await:\n"," concurrent.futures.wait(futures)\n"," \n"," \n","def parse_config(config:str):\n"," space_string = ' \\n\\r\\t\\'\\\",'\n"," other_flie_list = [item.split('#')[0].strip(space_string) for item in config.split('\\n') if item.strip(space_string)]\n"," other_flie_list = [item.strip() for item in other_flie_list if item.strip()]\n"," other_flie_list_store = {}\n"," other_flie_list_store_name='default'\n"," other_flie_list_store_list_cache=[]\n"," \n"," for item in other_flie_list:\n"," if item.startswith('[') and item.endswith(']'):\n"," if not other_flie_list_store_name == 'default':\n"," other_flie_list_store[other_flie_list_store_name]=other_flie_list_store_list_cache\n"," other_flie_list_store_list_cache = []\n"," other_flie_list_store_name = item[1:-1]\n"," else:\n"," other_flie_list_store_list_cache.append(item)\n"," other_flie_list_store[other_flie_list_store_name]=other_flie_list_store_list_cache\n"," \n"," return other_flie_list_store\n","\n","\n","def link_or_download_flie(config:str, skip_url:bool=False, _link_instead_of_copy:bool=True, base_path:str = '',\n"," sync:bool=False,thread_num:int=None, is_await:bool=False):\n"," store:dict[str,List[str]] = parse_config(config)\n"," download_list = []\n"," for dist_dir in store.keys():\n"," dist_path = os.path.join(base_path,dist_dir)\n"," os.makedirs(dist_path,exist_ok=True)\n"," for path in store[dist_dir]:\n"," if 'https://' in path or 'http://' in path:\n"," if skip_url:\n"," continue\n"," if sync:\n"," download_urls([pause_url(path,dist_path)],_link_instead_of_copy = _link_instead_of_copy, sync=sync)\n"," continue\n"," download_list.append(pause_url(path,dist_path))\n"," else:\n"," run(f'cp -n -r -f {\"-s\" if _link_instead_of_copy else \"\"} {path} {dist_path}')\n"," if show_shell_info:\n"," print(f'{\"链接\" if _link_instead_of_copy else \"复制\"} {path} --> {dist_path}')\n"," run(f'rm -f {dist_path}/\\*.* ')\n"," if not skip_url:\n"," if show_shell_info:\n"," pprint.pprint(download_list)\n"," download_urls(download_list,_link_instead_of_copy = _link_instead_of_copy, sync=sync, thread_num=thread_num or 3,is_await=is_await)"]},{"cell_type":"markdown","metadata":{"id":"p0uS-BLULCtD"},"source":["## kaggle public API\n","\n","**不能使用%cd这种会改变当前工作目录的命令,会导致和其他线程冲突**\n","\n","---"]},{"cell_type":"code","execution_count":null,"metadata":{"_kg_hide-input":true,"id":"m8FJi4j0LCtD","trusted":true},"outputs":[],"source":["# 安装kaggle的api token文件\n","def initKaggleConfig():\n"," if Path('~/.kaggle/kaggle.json').exists():\n"," return True\n"," if Path(kaggleApiTokenFile).exists():\n"," run(f'''mkdir -p ~/.kaggle/''')\n"," run('cp '+kaggleApiTokenFile+' ~/.kaggle/kaggle.json')\n"," run(f'''chmod 600 ~/.kaggle/kaggle.json''')\n"," return True\n"," print('缺少kaggle的apiToken文件,访问:https://www.kaggle.com/你的kaggle用户名/account 获取')\n"," return False\n","\n","def getUserName():\n"," if not initKaggleConfig(): return\n"," import kaggle\n"," return kaggle.KaggleApi().read_config_file()['username']\n","\n","def createOrUpdateDataSet(path:str,datasetName:str):\n"," if not initKaggleConfig(): return\n"," print('创建或更新数据集 '+datasetName)\n"," import kaggle\n"," run(f'mkdir -p {_install_path}/kaggle_cache')\n"," run(f'rm -rf {_install_path}/kaggle_cache/*')\n"," datasetDirPath = _install_path+'/kaggle_cache/'+datasetName\n"," run('mkdir -p '+datasetDirPath)\n"," run('cp -f '+path+' '+datasetDirPath+'/')\n"," username = getUserName()\n"," print(\"kaggle username:\"+username)\n"," datasetPath = username+'/'+datasetName\n"," datasetList = kaggle.api.dataset_list(mine=True,search=datasetPath)\n"," print(datasetList)\n"," if len(datasetList) == 0 or datasetPath not in [str(d) for d in datasetList]: # 创建 create\n"," run('kaggle datasets init -p' + datasetDirPath)\n"," metadataFile = datasetDirPath+'/dataset-metadata.json'\n"," run('sed -i s/INSERT_TITLE_HERE/'+ datasetName + '/g ' + metadataFile)\n"," run('sed -i s/INSERT_SLUG_HERE/'+ datasetName + '/g ' + metadataFile)\n"," run('cat '+metadataFile)\n"," run('kaggle datasets create -p '+datasetDirPath)\n"," print('create database done')\n"," else:\n"," kaggle.api.dataset_metadata(datasetPath,datasetDirPath)\n"," kaggle.api.dataset_create_version(datasetDirPath, 'auto update',dir_mode='zip')\n"," print('upload database done')\n","\n","def downloadDatasetFiles(datasetName:str,outputPath:str):\n"," if not initKaggleConfig(): return\n"," print('下载数据集文件 '+datasetName)\n"," import kaggle\n"," username = getUserName()\n"," datasetPath = username+'/'+datasetName\n"," datasetList = kaggle.api.dataset_list(mine=True,search=datasetPath)\n"," if datasetPath not in [str(d) for d in datasetList]:\n"," return False\n"," run('mkdir -p '+outputPath)\n"," kaggle.api.dataset_download_files(datasetPath,path=outputPath,unzip=True)\n"," return True\n","\n"]},{"cell_type":"markdown","metadata":{},"source":["## 同步文件夹到 huggingface\n","\n","---"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["# 文件夹与 huggingface 同步\n","if _huggingface_token:\n"," if not is_installed('watchdog'):\n"," requirements.append('watchdog')\n"," if not is_installed('huggingface_hub'):\n"," requirements.append('huggingface_hub')\n"," else:\n"," try:\n"," from huggingface_hub import HfApi,login,snapshot_download\n"," except:\n"," requirements.append('huggingface_hub')\n","\n","huggingface_is_init = False\n","\n","def init_huggingface():\n"," if not _huggingface_token:\n"," return False\n","\n"," global huggingface_headers\n"," global huggingface_is_init\n"," \n"," from huggingface_hub import login\n"," token = replace_path(_huggingface_token)\n"," if not _huggingface_token.startswith('hf_') and Path(token).exists():\n"," with open(token,encoding = \"utf-8\") as nkfile:\n"," token = nkfile.readline()\n"," if not token.startswith('hf_'):\n"," print('huggingface token 不正确,请将 token ��� 仅存放token 的txt文件路径填入 _huggingface_token 配置')\n"," return False\n"," login(token,add_to_git_credential=True)\n"," huggingface_headers = {'Authorization': 'Bearer '+token}\n"," print('huggingface token 已经加载,可以下载私有仓库或文件')\n"," \n"," huggingface_is_init = True\n"," return True\n","\n","\n","def start_sync_log_to_huggingface(repo_id:str,directory_to_watch,repo_type='dataset',file_types=['.png','.jpg','.txt','.webp','.jpeg']):\n"," if not huggingface_is_init:\n"," print('huggingface 相关功能未初始化 请调用 init_huggingface() 初始化')\n"," \n"," if not directory_to_watch:\n"," print('请指定需要同步的本地目录 directory_to_watch')\n"," return\n"," if not Path(directory_to_watch).exists():\n"," run(f'mkdir -p {directory_to_watch}')\n"," from watchdog.observers import Observer\n"," from watchdog.events import FileSystemEventHandler\n"," from huggingface_hub import HfApi,login,snapshot_download\n"," \n"," # 配置监视的目录和 Hugging Face 仓库信息\n"," class FileChangeHandler(FileSystemEventHandler):\n"," def __init__(self, api, repo_id, repo_type,directory_to_watch):\n"," self.api = api\n"," self.repo_id = repo_id\n"," self.repo_type = repo_type\n"," self.directory_to_watch = directory_to_watch\n"," def on_created(self, event):\n"," if not event.is_directory:\n"," # 上传新文件到 Hugging Face 仓库\n"," file_path = event.src_path\n"," file_name:str = os.path.basename(file_path)\n"," print(file_name)\n"," if file_name[file_name.rindex('.'):] not in file_types: return\n"," print(file_name,'>>','huggingface')\n"," try:\n"," self.api.upload_file(\n"," path_or_fileobj=file_path,\n"," path_in_repo=file_path.replace(self.directory_to_watch,''),\n"," repo_id=self.repo_id,\n"," repo_type=self.repo_type,\n"," )\n"," except IOError as error:\n"," print(error)\n","\n"," def on_deleted(self, event):\n"," if not event.is_directory:\n"," # 从 Hugging Face 仓库删除文件\n"," file_path = event.src_path\n"," file_name = os.path.basename(file_path)\n"," if file_name[file_name.rindex('.'):] not in file_types: return\n"," try:\n"," self.api.delete_file(\n"," path_in_repo=file_path.replace(self.directory_to_watch,''),\n"," repo_id=self.repo_id,\n"," repo_type=self.repo_type,\n"," )\n"," except IOError as error:\n"," print(error)\n","\n"," def on_modified(self, event):\n"," if not event.is_directory:\n"," # 更新 Hugging Face 仓库中的文件\n"," file_path = event.src_path\n"," file_name = os.path.basename(file_path)\n"," if file_name[file_name.rindex('.'):] not in ['.png','.jpg','.txt','.webp','.jpeg']: return\n"," try:\n"," self.api.upload_file(\n"," path_or_fileobj=file_path,\n"," path_in_repo=file_path.replace(self.directory_to_watch,''),\n"," repo_id=self.repo_id,\n"," repo_type=self.repo_type,\n"," )\n"," except IOError as error:\n"," print(error)\n","\n"," def on_moved(self, event):\n"," if not event.is_directory:\n"," file_path = event.dest_path\n"," file_name = os.path.basename(file_path)\n"," if file_name[file_name.rindex('.'):] not in file_types: return\n"," if event.dest_path.startswith(self.directory_to_watch):\n"," try:\n"," self.api.upload_file(\n"," path_or_fileobj=file_path,\n"," path_in_repo=file_path.replace(self.directory_to_watch,''),\n"," repo_id=self.repo_id,\n"," repo_type=self.repo_type,\n"," )\n"," except IOError as error:\n"," print(error)\n","\n"," api = HfApi()\n"," \n"," # 创建观察者对象并注册文件变化处理程序\n"," event_handler = FileChangeHandler(api,repo_id,repo_type,directory_to_watch)\n"," observer = Observer()\n"," observer.schedule(event_handler, directory_to_watch, recursive=True)\n","\n"," # 启动观察者\n"," observer.name = \"solo_directory_to_watch\"\n"," print(f'启动目录同步,{directory_to_watch} 将自动同步到 huggingface {repo_type} : {repo_id}')\n"," observer.start()"]},{"cell_type":"markdown","metadata":{"id":"sswa04veLCtE"},"source":["## 工具函数\n","**不能使用%cd这种会改变当前工作目录的命令,会导致和其他线程冲突**\n","\n","---"]},{"cell_type":"code","execution_count":null,"metadata":{"_kg_hide-input":true,"trusted":true},"outputs":[],"source":["\n","def zipPath(path:str,zipName:str,format='tar'):\n"," if path.startswith('$install_path'):\n"," path = path.replace('$install_path',_install_path)\n"," if path.startswith('$output_path'):\n"," path = path.replace('$install_path',_output_path)\n"," if not path.startswith('/'):\n"," path = f'{_install_path}/{_ui_dir_name}/{path}'\n"," if Path(path).exists():\n"," if 'tar' == format:\n"," run(f'tar -cf {_output_path}/'+ zipName +'.tar -C '+ path +' . ')\n"," elif 'gz' == format:\n"," run(f'tar -czf {_output_path}/'+ zipName +'.tar.gz -C '+ path +' . ')\n"," return\n"," print('指定的目录不存在:'+path)\n"]},{"cell_type":"markdown","metadata":{},"source":["## 内网穿透\n","\n","---"]},{"cell_type":"code","execution_count":null,"metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"id":"coqQvTSLLCtE","trusted":true},"outputs":[],"source":["def printUrl(url,name=''):\n"," print(f'{name} 访问地址:{url}')\n"," for key in sorted(_proxy_path.keys(), key=len)[::-1]:\n"," print(f'{name} 本地服务:{_proxy_path[key]} 访问地址:{url}{key}')\n","# ngrok\n","def startNgrok(ngrokToken:str,ngrokLocalPort:int):\n"," if not is_installed('pyngrok'):\n"," run('pip install pyngrok')\n"," from pyngrok import conf, ngrok\n"," try:\n"," conf.get_default().auth_token = ngrokToken\n"," conf.get_default().monitor_thread = False\n"," ssh_tunnels = ngrok.get_tunnels(conf.get_default())\n"," url = ''\n"," if len(ssh_tunnels) == 0:\n"," ssh_tunnel = ngrok.connect(ngrokLocalPort)\n"," url = ssh_tunnel.public_url\n"," print('ngrok 访问地址:'+ssh_tunnel.public_url)\n"," else:\n"," print('ngrok 访问地址:'+ssh_tunnels[0].public_url)\n"," url = ssh_tunnels[0].public_url\n"," printUrl(url,'ngrok')\n"," def auto_request_ngrok():\n"," if url:\n"," while(_runing):\n"," time.sleep(60*1)\n"," try:\n"," res = requests.get(url+'/',headers={\"ngrok-skip-browser-warning\" : \"1\"},timeout=10)\n"," except:\n"," ''\n"," # print('自动调用ngrok链接以保存链接不会断开',res.status_code)\n","\n"," # threading.Thread(target = auto_request_ngrok,daemon=True,name='solo_auto_request_ngrok').start()\n"," except:\n"," print('启动ngrok出错')\n"," \n","def load_frpc_config(conf_or_file,dost_port=None):\n"," frpcStartArg = ''\n"," _frp_temp_config_file = ''\n"," _frp_config_or_file = conf_or_file\n"," run(f'''mkdir -p {_install_path}/configFiles''')\n"," if _frp_config_or_file:\n"," if '[common]' in _frp_config_or_file:\n"," echoToFile(_frp_config_or_file,f'{_install_path}/configFiles/temp_frpc_{dost_port or _server_port}.ini')\n"," _frp_temp_config_file = f'{_install_path}/configFiles/temp_frpc_{dost_port or _server_port}.ini'\n"," elif '.ini' in _frp_config_or_file:\n"," _frp_temp_config_file = _frp_config_or_file.strip()\n"," \n"," if _frp_temp_config_file:\n"," if Path(_frp_temp_config_file).exists():\n"," run(f'''cp -f {_frp_temp_config_file} {_install_path}/configFiles/frpc_{dost_port or _server_port}.ini''')\n"," run(f'''sed -i \"s/local_port = .*/local_port = {dost_port or _server_port}/g\" {_install_path}/configFiles/frpc_{dost_port or _server_port}.ini''')\n"," frpcStartArg = f' -c {_install_path}/configFiles/frpc_{dost_port or _server_port}.ini'\n"," elif _frp_config_or_file.strip().startswith('-f'):\n"," frpcStartArg = _frp_config_or_file.strip()\n"," return frpcStartArg\n","\n","def startFrpc(name,configFile):\n"," if not Path(f'{_install_path}/frpc/frpc').exists():\n"," installFrpExe()\n"," if freefrp_url:\n"," printUrl(freefrp_url,'freefrp')\n"," echoToFile(f'''\n","cd {_install_path}/frpc/\n","{_install_path}/frpc/frpc {configFile}\n","''',f'{_install_path}/frpc/start.sh')\n"," get_ipython().system(f'''bash {_install_path}/frpc/start.sh''')\n"," \n","def installFrpExe():\n"," if _useFrpc:\n"," print('安装frpc')\n"," run(f'mkdir -p {_install_path}/frpc')\n"," if Path(frpcExePath).exists():\n"," run(f'cp -f -n {frpcExePath} {_install_path}/frpc/frpc')\n"," else:\n"," run(f'wget \"https://huggingface.co/datasets/ACCA225/Frp/resolve/main/frpc\" -O {_install_path}/frpc/frpc')\n"," \n"," for ssl in frpcSSLFFlies:\n"," if Path(ssl).exists():\n"," run(f'cp -f -n {ssl}/* {_install_path}/frpc/')\n"," run(f'chmod +x {_install_path}/frpc/frpc')\n"," run(f'{_install_path}/frpc/frpc -v')\n","\n","def startProxy():\n"," if _useNgrok:\n"," startNgrok(ngrokToken,_server_port)\n"," if _useFrpc:\n"," startFrpc('frpc_proxy',frpcStartArg)"]},{"cell_type":"markdown","metadata":{},"source":["## NGINX 反向代理\n","\n","---"]},{"cell_type":"code","execution_count":null,"metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"trusted":true},"outputs":[],"source":["\n","# nginx 反向代理配置文件\n","def localProxy():\n"," def getProxyLocation(subPath:str, localServer:str):\n"," return '''\n"," location '''+ subPath +'''\n"," {\n"," proxy_pass '''+ localServer +''';\n"," proxy_set_header Host $host;\n"," proxy_set_header X-Real-IP $remote_addr;\n"," proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n"," proxy_set_header REMOTE-HOST $remote_addr;\n"," proxy_set_header Upgrade $http_upgrade;\n"," proxy_set_header Connection upgrade;\n"," proxy_http_version 1.1;\n"," proxy_connect_timeout 10m;\n"," proxy_read_timeout 10m;\n"," }\n"," \n"," '''\n"," \n"," conf = '''\n","server\n","{\n"," listen '''+str(_server_port)+''';\n"," listen [::]:'''+str(_server_port)+''';\n"," server_name 127.0.0.1 localhost 0.0.0.0 \"\";\n"," \n"," if ($request_method = OPTIONS) {\n"," return 200;\n"," }\n"," fastcgi_send_timeout 10m;\n"," fastcgi_read_timeout 10m;\n"," fastcgi_connect_timeout 10m;\n"," \n"," '''+ ''.join([getProxyLocation(key,_proxy_path[key]) for key in sorted(_proxy_path.keys(), key=len)[::-1]]) +'''\n","}\n","'''\n"," echoToFile(conf,'/etc/nginx/conf.d/proxy_nginx.conf')\n"," if not check_service('localhost',_server_port):\n"," run(f'''nginx -c /etc/nginx/nginx.conf''')\n"," run(f'''nginx -s reload''')"]},{"cell_type":"markdown","metadata":{},"source":["## 线程清理工具\n","\n","---\n","\n","清理线程名以 solo_ 开头的所有线程"]},{"cell_type":"code","execution_count":null,"metadata":{"_kg_hide-input":true,"trusted":true},"outputs":[],"source":["import inspect\n","import ctypes\n","\n","def _async_raise(tid, exctype):\n"," \"\"\"raises the exception, performs cleanup if needed\"\"\"\n"," tid = ctypes.c_long(tid)\n"," if not inspect.isclass(exctype):\n"," exctype = type(exctype)\n"," res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))\n"," if res == 0:\n"," raise ValueError(\"invalid thread id\")\n"," elif res != 1:\n"," # \"\"\"if it returns a number greater than one, you're in trouble,\n"," # and you should call it again with exc=NULL to revert the effect\"\"\"\n"," ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)\n"," raise SystemError(\"PyThreadState_SetAsyncExc failed\")\n","\n","def stop_thread(thread):\n"," _async_raise(thread.ident, SystemExit)\n","\n","def stop_solo_threads():\n"," global _runing\n"," _runing = False\n"," # 获取当前所有活动的线程\n"," threads = threading.enumerate()\n"," # 关闭之前创建的子线程\n"," for thread in threads:\n"," if thread.name.startswith('solo_'):\n"," print(f'结束线程:{thread.name}')\n"," try:\n"," stop_thread(thread)\n"," except socket.error:\n"," print(f'结束线程:{thread.name} 执行失败')\n"," "]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["docs = '''\n","# 配置项\n","server_port int 本地服务端口,穿透使用的端口\n","huggingface_token string huggingface token,用于同步文件或者下载需要登录的文件\n","hidden_console_info bool 是否隐藏控制台信息\n","proxy_path {string:string} 将哪个路径映射到哪个服务,格式为:{'/':'http://127.0.0.1:5000/'}\n","kaggle_api_token string kaggle api token,用于访问kaggle的api\n","ngrok_config_or_file ngrok的token文件内容或者放token的文件的路径\n","frp_config_or_file frp的配置内容或者配置文件的路径\n","frp_ssl_dir frp的https证书存放目录\n","# 工具函数\n","执行cmd命令:\n","run(command, cwd=None, desc=None, errdesc=None, custom_env=None,try_error:bool=True)\n","检查网络是否可以访问\n","check_service(host, port)\n","检查gpu是否存在\n","check_gpu()\n","写入文本到文件\n","echoToFile(content:str,path:str)\n","获取一个免费frp配置\n","get_freefrp_confog(local_port)\n","\n","下载文件\n","link_or_download_flie(config:str, \n","skip_url:bool=False, \n","_link_instead_of_copy:bool=True, \n","base_path:str = '',\n","sync:bool=False, # 同步且按顺序下载\n","thread_num:int=None, \n","is_await:bool=False) # 异步不按顺序但等待下载完成\n","---- 下载文件功能的配置的格式\n","[目标目录] # 中括号必须写\n","下载链接1\n","名称:下载链接2 # 链接前面的名称可以用于对文件重命名\n","# 备注 井号后面的内容会被忽略\n","可以下载git仓库\n","可以下载huggingfacec仓库或者文件,会使用 huggingface_token 作为凭证下载\n","可以下载其他可以直接下载的互联网资源\n","可以作为文件链接功能,将某个目录或目录下的全部文件链接到目标目录\n","---- 下载文件功能结束结束\n","\n","创建kaggle数据集\n","createOrUpdateDataSet(path:str,datasetName:str)\n","下载kaggle数据集\n","downloadDatasetFiles(datasetName:str,outputPath:str)\n","同步目录到huggingface,可指定同步的文件类型\n","start_sync_log_to_huggingface(repo_id:str,directory_to_watch,repo_type='dataset',file_types=['.png','.jpg','.txt','.webp','.jpeg'])\n","压缩指定目录到指定位置\n","zipPath(path:str,zipName:str,format='tar') # 可用tar或gz\n","停止后台线程 # 仅停止线程名称前缀为 solo_ 的线程\n","stop_solo_threads()\n","'''\n","def get_docs():\n"," print(docs)\n"," \n","print('可以执行get_docs()查看文档')"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["if not (True if os.getenv('IS_INSTALL_NGINX','False') == 'True' else False):\n"," run('git lfs install')\n"," run('git config --global credential.helper store')\n"," run('sudo apt update -y')\n"," run('sudo apt install nginx -y')\n"," os.environ['IS_INSTALL_NGINX'] = 'True'\n","stop_solo_threads()\n","time.sleep(2)\n","threading.Thread(target = startProxy, daemon=True, name='solo_startProxy').start()\n","localProxy()\n","init_huggingface()"]}],"metadata":{"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"datasetId":2716934,"sourceId":6167400,"sourceType":"datasetVersion"},{"datasetId":3654544,"sourceId":6346544,"sourceType":"datasetVersion"},{"datasetId":2962375,"sourceId":6720235,"sourceType":"datasetVersion"},{"datasetId":3074484,"sourceId":6817788,"sourceType":"datasetVersion"}],"isGpuEnabled":true,"isInternetEnabled":true,"language":"python","sourceType":"notebook"},"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.10.13"}},"nbformat":4,"nbformat_minor":4}
|
|
|
|
|
|
lite-start.ipynb
DELETED
|
@@ -1 +0,0 @@
|
|
| 1 |
-
{"cells":[{"cell_type":"markdown","metadata":{},"source":["# NovelAi stable-diffusion-webui+api+sdxl\n","---\n","**version: 1.6.0 • python: 3.10.6 • torch: 2.0.1+cu118 • xformers: 0.0.21 • gradio: 3.41.2**\n","- 发布地址 [kaggle stable-diffusion-webui-novelai](https://www.kaggle.com/code/yiyiooo/stable-diffusion-webui-novelai)\n","- 这是一个用于快速体验ai绘画项目 [stable-diffusion-webui](https://github.com/AUTOMATIC1111/stable-diffusion-webui) 的笔记本,你可以直接启动就能在线体验ai绘图的乐趣。 \n","- kaggle和colab都是AI学习平台,请勿浪费计算资源,如果有需求,可以考虑AutoDL这类租用显卡的平台或者colab付费使用。\n","- 在保持可以免配置直接启动的情况下也提供了很多可自定义的配置,在下方的配置项里,请自行查看。 \n","- 同时也为新人提供了一份基础的帮助文档,包含了一些使用中可能遇到的问题,如果使用过程中有什么疑问,不妨先看看帮助文档。\n","- 如果你需要在此脚本上修改再发布,请随意,但请遵守相关法律法规,文明使用。\n","- 使用时如果遇到问题,尽可能通过帮助文档或者参考已有内容尝试自己解决。\n","- Q群 [816545732](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=OGQydingTPku9M_myV_cscWv6MVaCSde&authKey=RFadQ18FgReFkx7CRs8SNk4vHpxHz%2FD2ojHL3433MehuQOBlnG0hhWFIo8AX%2BFRU&noverify=0&group_code=816545732) ,这是我建的新群,如果有需要,可以进群,其实这个笔记已经非常简洁了,进群大概也不会有啥帮助。\n","- 使用前可以看一下最后的更新日志,可能有功能更新需要注意"]},{"cell_type":"markdown","metadata":{},"source":["## 重要文件列表\n","\n","- **这个列表仅加载一次 且会等待加载完成再开始安装sd**\n","- ```[]```内的是下载文件的目标目录,可以是相对目录也可以是觉得路径\n","- ```[]```的下一行就是文件列表,可以是下载地址、git仓库、文件路径、文件夹路径,且支持通配符\n","- 如果需要对下载的文件重命名,可以在下载链接前面写上文件名后加一个```:```分开文件名和下载地址\n","- 如果需要下载到其他目录,可以使用同样的格式写其他目录"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["before_downloading = '''# 这个列表仅加载一次 且会等待加载完成再开始安装sd\n","[extensions] # 插件\n","https://github.com/dtlnor/stable-diffusion-webui-localization-zh_CN.git\n","https://github.com/AlUlkesh/stable-diffusion-webui-images-browser.git\n","https://github.com/DominikDoom/a1111-sd-webui-tagcomplete.git\n","https://github.com/Mikubill/sd-webui-controlnet.git\n","https://github.com/ilian6806/stable-diffusion-webui-state.git\n","https://github.com/pkuliyi2015/multidiffusion-upscaler-for-automatic1111.git\n","https://github.com/Bing-su/adetailer.git\n","https://github.com/zanllp/sd-webui-infinite-image-browsing.git\n","https://github.com/viyiviyi/stable-diffusion-webui-zoomimage.git\n","https://github.com/viyiviyi/prompts-filter.git zz_prompts-filter\n","https://github.com/viyiviyi/sd-encrypt-image.git # 图片加密插件,解决涩图封号问题,需要在参数里设置你的密码开启\n","https://github.com/nonnonstop/sd-webui-3d-open-pose-editor.git\n","https://github.com/jexom/sd-webui-depth-lib.git\n","https://github.com/Elldreth/loopback_scaler.git\n","https://github.com/hnmr293/sd-webui-cutoff.git\n","https://github.com/hako-mikan/sd-webui-lora-block-weight.git\n","https://github.com/viyiviyi/Stable-Diffusion-Webui-Civitai-Helper.git # 修改过的c站助手,下载的缩略图可以被加密插件加密\n","https://github.com/viyiviyi/sd-civitai-browser-plus.git\n","https://github.com/adieyal/sd-dynamic-prompts.git\n","https://github.com/hako-mikan/sd-webui-supermerger.git\n","https://github.com/thisjam/sd-webui-oldsix-prompt.git\n","https://github.com/NoCrypt/sd-fast-pnginfo.git\n","https://github.com/ArtVentureX/sd-webui-agent-scheduler.git\n","https://github.com/continue-revolution/sd-webui-animatediff.git animatediff\n","https://github.com/mcmonkeyprojects/sd-dynamic-thresholding.git\n","\n","# 如果你有模型文件需要在启动前加载,可以写在这个下面对应位置\n","\n","[models/Stable-diffusion] # 大模型列表\n","\n","[models/hypernetworks] # hypernetworks文件列表\n","\n","[models/embeddings] # embeddings文件列表\n","\n","[models/Lora] # Lora文件列表\n","\n","[models/VAE] # VAE文件列表\n","\n","[extensions/sd-webui-controlnet/models] # controlnet插件的模型列表\n","\n","# 通过这个功能安装一个ComfyUI\n","[{install_path}]\n","https://github.com/comfyanonymous/ComfyUI.git ComfyUI\n","\n","[{install_path}/ComfyUI/custom_nodes] # ComfyUI 节点模块\n","https://github.com/viyiviyi/comfyui-encrypt-image.git # 加密���件,安装后就会加密,默认密码123qwe,在utils下增加了一个预览和设置密码的节点\n","https://github.com/ltdrdata/ComfyUI-Manager.git\n","https://github.com/Suzie1/ComfyUI_Comfyroll_CustomNodes.git\n","https://github.com/cubiq/ComfyUI_IPAdapter_plus.git\n","https://github.com/jags111/efficiency-nodes-comfyui.git\n","https://github.com/twri/sdxl_prompt_styler.git\n","https://github.com/ssitu/ComfyUI_UltimateSDUpscale --recursive\n","https://github.com/ltdrdata/ComfyUI-Impact-Pack.git\n","https://github.com/ltdrdata/ComfyUI-Inspire-Pack.git\n","https://github.com/giriss/comfy-image-saver.git\n","https://github.com/Kosinkadink/ComfyUI-AnimateDiff-Evolved.git AnimateDiff\n","https://github.com/SLAPaper/ComfyUI-Image-Selector.git\n","https://github.com/Kosinkadink/ComfyUI-VideoHelperSuite.git\n","https://github.com/Fannovel16/comfyui_controlnet_aux.git\n","https://github.com/mav-rik/facerestore_cf.git\n","https://github.com/FizzleDorf/ComfyUI_FizzNodes.git\n","https://github.com/BadCafeCode/masquerade-nodes-comfyui.git\n","https://github.com/WASasquatch/was-node-suite-comfyui.git\n","https://github.com/YMC-GitHub/ymc-node-suite-comfyui.git\n","https://github.com/coreyryanhanson/ComfyQR.git\n","https://github.com/melMass/comfy_mtb.git\n","https://github.com/sipherxyz/comfyui-art-venture.git\n","https://github.com/cubiq/ComfyUI_essentials.git\n","https://github.com/Gourieff/comfyui-reactor-node.git\n","\n","[{install_path}/ComfyUI/web/extensions] # ComfyUI web插件\n","https://github.com/viyiviyi/comfyui-mobile.git\n","https://github.com/viyiviyi/comfyui-popup-image-prevew.git\n","\n","'''"]},{"cell_type":"markdown","metadata":{},"source":["## 普通文件列表\n","\n","- **这个列表仅加载一次 且不会等待加载完成**\n","- ```[]```内的是下载文件的目标目录,可以是相对目录也可以是觉得路径\n","- ```[]```的下一行就是文件列表,可以是下载地址、git仓库、文件路径、文件夹路径,且支持通配符\n","- 如果需要对下载的文件重命名,可以在下载链接前面写上文件名后加一个```:```分开文件名和下载地址\n","- 如果需要下载到其他目录,可以使用同样的格式写其他目录"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["async_downloading='''# 这个列表仅加载一次 且不会等待加载完成\n","[extensions] # 插件 如果你没有使用ngrok或者frpc,请不要把插件放在这里加载,因为这里的文件可能在webui启动后才加载完成\n","\n","[models/ESRGAN]\n","https://huggingface.co/lokCX/4x-Ultrasharp/blob/main/4x-UltraSharp.pth\n","\n","[models/VAE] # VAE文件列表\n","{input_path}/vae-ft-ema-prunedsafetensors/vae-ft-ema-560000-ema-pruned.safetensors\n","{input_path}/vae-ft-ema-prunedsafetensors/vae-ft-mse-840000-ema-pruned.safetensors\n","sdxl_vae.safetensors:https://huggingface.co/madebyollin/sdxl-vae-fp16-fix/resolve/main/sdxl_vae.safetensors?download=true # sdxl模型需要sdxl的vae\n","\n","[models/Stable-diffusion] # 大模型列表\n","# https://civitai.com/api/download/models/293564\n","/kaggle/input/anime-xl/animagineXLV3_v30.safetensors\n","/kaggle/input/kohakuxl/kohaku-xl-delta-rev.safetensors\n","\n","[models/hypernetworks] # hypernetworks文件列表\n","\n","[models/embeddings] # embeddings文件列表\n","\n","[models/Lora] # Lora文件列表\n","https://civitai.com/api/download/models/116970\n","https://civitai.com/api/download/models/117151 # Clothing +/- Adjuster 衣物增/减 LoRA\n","https://civitai.com/api/download/models/62833 # Detail Tweaker LoRA (细节调整LoRA)\n","\n","\n","[extensions/sd-webui-controlnet/models] # controlnet插件的模型列表\n","# https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11e_sd15_ip2p_fp16.safetensors\n","# https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11e_sd15_shuffle_fp16.safetensors\n","# https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11f1e_sd15_tile_fp16.safetensors\n","# https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11f1p_sd15_depth_fp16.safetensors\n","https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_canny_fp16.safetensors\n","# https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_inpaint_fp16.safetensors\n","https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_lineart_fp16.safetensors\n","# https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_mlsd_fp16.safetensors\n","# https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_normalbae_fp16.safetensors\n","https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_openpose_fp16.safetensors\n","# https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_scribble_fp16.safetensors\n","# https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_seg_fp16.safetensors\n","# https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_softedge_fp16.safetensors\n","https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15s2_lineart_anime_fp16.safetensors\n","# https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11u_sd15_tile_fp16.safetensors\n","\n","[extensions/animatediff/model] # animatediff 插件基本模型\n","# https://huggingface.co/guoyww/animatediff/resolve/cd71ae134a27ec6008b968d6419952b0c0494cf2/mm_sd_v15_v2.ckpt\n","\n","[models/Lora/animatediff] # animatediff lora模型\n","# https://huggingface.co/guoyww/animatediff/resolve/cd71ae134a27ec6008b968d6419952b0c0494cf2/v2_lora_PanLeft.ckpt\n","'''\n"]},{"cell_type":"markdown","metadata":{},"source":["## 按顺序加载的重要文件列表\n","\n","- **这个列表每次 run all 启动都会加载一次,且一定按照顺序加载后才启动webui**\n","- ```[]```内的是下载文件的目标目录,可以是相对目录也可以是觉得路径\n","- ```[]```的下一行就是文件列表,可以是下载地址、git仓库、文件路径、文件夹路径,且支持通配符\n","- 如果需要对下载的文件重命名,可以在下载链接前面写上文件名后加一个```:```分开文件名和下载地址\n","- 如果需要下载到其他目录,可以使用同样的格式写其他目录"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["before_start_sync_downloading = ''' # 这个列表每次 run all 启动都会加载一次,且一定按照顺序加载\n","\n","# 如果你需要每次启动都加载一下文件,可以写在这。(比如测试路径是否正确的时候)\n","\n","[models/Stable-diffusion] # 大模型列表\n","\n","[models/hypernetworks] # hypernetworks文件列表\n","\n","[models/embeddings] # embeddings文件列表\n","\n","[models/Lora] # Lora文件列表\n","\n","[models/VAE] # VAE文件列表\n","\n","[extensions/sd-webui-controlnet/models] # controlnet插件的模型列表\n","\n","'''"]},{"cell_type":"markdown","metadata":{},"source":["## webui 启动参数\n","- 所有的参数都会在启动时传入\n","- 可以在前面加```#```来屏蔽某个参数\n","- 端口参数需要在下一个代码块的```webuiPort```处修改"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["sd_start_args='''\n","# --ckpt=mg-Tender.safetensors # 默认模型名称,路径不能包含空格\n","--disable-safe-unpickle \n","--deepdanbooru \n","--no-hashing \n","--no-download-sd-model \n","--administrator\n","--skip-torch-cuda-test \n","--skip-version-check \n","--disable-nan-check\n","--opt-sdp-attention \n","--opt-sdp-no-mem-attention \n","--xformers-flash-attention\n","--xformers\n","--api \n","--listen\n","--lowram\n","#--no-gradio-queue\n","--encrypt-pass=123qwe # 图片加密插件的密码,如果要启用图片加密插件,删除这一行前面的#和将123qwe改成你的密码,也可以不改\n","# --share # 默认的内网穿透在kaggle和colab都已经不可用,请考虑其他方案\n","--disable-console-progressbars\n","--no-half-vae \n","# --no-half #关闭半精度\n","# --enable-console-prompts\n","# --nowebui # 如果只需要api服务,可以开启这个\n","# --api-auth=2333:6666 # api密码\n","# --gradio-auth=2333:6666 # webui密码\n","'''"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# 这个方法内的函数会在所有文件加载完成,准备启动前执行,可以放一些自定义的逻辑功能\n","def on_before_start():\n"," '''这是一个空的函数'''\n"," run(f'{_install_path}/{_ui_dir_name}/venv/bin/python3 -s -m pip install insightface',cwd=os.path.join(f'{install_path}/{ui_dir_name}',node))\n"," def get_folder_list(directory:str): \n"," folder_list = [] \n"," for item in os.listdir(directory): \n"," if os.path.isdir(os.path.join(directory, item)): \n"," folder_list.append(item) \n"," return folder_list \n"," # 启动 ComfyUI\n"," def start_comfyui():\n"," !rm -rf {install_path}/ComfyUI/models/checkpoints\n"," !ln -s -r {_install_path}/{_ui_dir_name}/models/Stable-diffusion {install_path}/ComfyUI/models/checkpoints\n"," !rm -rf {install_path}/ComfyUI/models/embeddings\n"," !ln -s -r {_install_path}/{_ui_dir_name}/embeddings {install_path}/ComfyUI/models/embeddings\n"," !rm -rf {install_path}/ComfyUI/models/loras\n"," !ln -s -r {_install_path}/{_ui_dir_name}/models/Lora {install_path}/ComfyUI/models/loras\n"," !rm -rf {install_path}/ComfyUI/models/vae\n"," !ln -s -r {_install_path}/{_ui_dir_name}/models/VAE {install_path}/ComfyUI/models/vae\n"," !rm -rf {install_path}/ComfyUI/models/hypernetworks\n"," !ln -s -r {_install_path}/{_ui_dir_name}/models/hypernetworks {install_path}/ComfyUI/models/hypernetworks\n"," !rm -rf {install_path}/ComfyUI/models/upscale_models\n"," !ln -s -r {_install_path}/{_ui_dir_name}/models/ESRGAN {install_path}/ComfyUI/models/upscale_models\n"," !rm -rf {install_path}/ComfyUI/models/controlnet\n"," !ln -s -r {_install_path}/{_ui_dir_name}/extensions/sd-webui-controlnet/models {install_path}/ComfyUI/models/controlnet\n"," !rm -rf {install_path}/ComfyUI/custom_nodes/AnimateDiff/models\n"," !ln -s -r {_install_path}/{_ui_dir_name}/extensions/animatediff/model {install_path}/ComfyUI/custom_nodes/AnimateDiff/models\n"," !rm -rf {install_path}/ComfyUI/custom_nodes/AnimateDiff/motion_lora\n"," !ln -s -r {_install_path}/{_ui_dir_name}/models/Lora/animatediff {install_path}/ComfyUI/custom_nodes/AnimateDiff/motion_lora\n"," _cwd = os.getcwd()\n"," \n"," def start(device:int):\n"," print(f'启动 comfyui {device}')\n"," %cd {install_path}/ComfyUI \n"," !{_install_path}/{_ui_dir_name}/venv/bin/python3 main.py --force-fp16 --cuda-device={device} --port={8188+device}\n"," %cd {_cwd}\n"," print(f'下载 comfyui 各节点的依赖')\n"," for node in get_folder_list(f'{install_path}/ComfyUI/custom_nodes'):\n"," print(os.path.join(f'{install_path}/ComfyUI/custom_nodes',node))\n"," if Path(os.path.join(f'{install_path}/ComfyUI/custom_nodes',node,'requirements.txt')).exists():\n"," run(f'{_install_path}/{_ui_dir_name}/venv/bin/python3 -s -m pip install -r requirements.txt',cwd=os.path.join(f'{install_path}/ComfyUI/custom_nodes',node))\n"," \n"," print(f'启动 comfyui')\n"," for device in range(torch.cuda.device_count() if _multi_case else 1):\n"," threading.Thread(target = start, daemon=True,args=([device]), name=f'solo_start_comfyui_{device}').start()\n"," \n"," threading.Thread(target = start_comfyui, daemon=True, name='solo_start_comfyui').start()\n"," \n"," # 安装一个文件浏览器 通过在访问地址后加 /fslist/ 访问\n"," def start_filebrower():\n"," !curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash\n"," !filebrowser -p 8012 --username admin -b /fslist -r {install_path}\n"," \n"," threading.Thread(target = start_filebrower, daemon=True, name='solo_start_filebrower').start()\n"," ## 下面可以写更多自定义逻辑"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["useGooglrDrive = True # 连接到谷歌云盘 在google colab环境才会生效\n","#Ngrok\n","useNgrok=True # 非必填 是否使用ngrok作为公网访问地址\n","#Frpc\n","useFrpc=True # 开启frp将不能启动\n","\n","#可以填写文件路径 或 直接填 token 内容\n","ngrok_config_or_file = '''\n","{input_path}/configs/ngrok_token.txt\n","'''\n","frp_config_or_file = '''\n","{input_path}/configs/frpc_koishi.ini\n","'''\n","frp_ssl_dir = '''\n","{input_path}/configs/koishi_ssl\n","'''\n","\n","# 配置启动参数\n","server_port=7860 # webui 默认端口\n","\n","# 仓库地址 这是修改过界面布局顺序的webui,不定期同步到官方版本\n","# 如果要使用官方版本,改成这个: https://github.com/AUTOMATIC1111/stable-diffusion-webui\n","sd_git_repo='https://github.com/viyiviyi/stable-diffusion-webui.git -b local-1.9' \n","# 配置文件,包括webui的设置和UI默认值,如果要自定义,fork这个仓库后修改并把地址替换这个地址\n","sd_config_git_repu = 'https://github.com/viyiviyi/sd-configs.git -b main-yiyiooo'\n","# 设置文件保存路径 当使用谷歌云盘时非常有用\n","setting_file = '{output_path}/configs/config.json'\n","ui_config_file = '{output_path}/configs/ui-config.json'\n","\n","# 这是配置文件夹同步的相关配置\n","# 需要在huggingface创建一个数据集(datasets) 然后把数据集的名称(在页面上有复制的按钮)填到 huggingface_repo \n","# 需要获取 token 填到 huggingface_token 获取的地址是: https://huggingface.co/settings/tokens\n","huggingface_token = '{input_path}/configs/huggingface_token.txt'\n","huggingface_repo = 'viyi/sdwui-log'\n","\n","# 自定义本地反向代理 这些配置将会成为nginx的反向代理配置,用于实现一个穿透访问多个实例\n","# 默认情况下 / 被代理到了webui;/1/ 被代理到了第二个webui\n","proxy_path={\n"," '/cui/':'http://127.0.0.1:8188/',\n"," '/cui2/':'http://127.0.0.1:8189/',\n"," '/fslist/':'http://127.0.0.1:8012/',\n","} # 增加一个comfyui的代理\n","\n","multi_case = True"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["link_instead_of_copy = True # 下载或加载Input的文件时是使用链接还是复制的方式加载到目标目录\n","hidden_console_info = True # 是否隐藏大部分的控制台内容"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["# 保存当前目录和启动时cd到之前保存的目录,可以减少sdwui-start-new.ipynb文件下载次数\n","import os\n","INIT_WORK_PATH = os.environ['HOME']\n","if os.getenv('INIT_WORK_PATH',''):\n"," INIT_WORK_PATH = os.getenv('INIT_WORK_PATH','')\n","else:\n"," os.environ['INIT_WORK_PATH'] = os.getcwd()\n","%cd {INIT_WORK_PATH}"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["reLoad = True\n","# 如果需要重新安装,请注释下面这一行\n","reLoad = False"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["import signal \n","import sys\n","\n","def auto_exit(signum,frame):\n"," print('自动结束运行')\n"," signal.alarm(0)\n"," sys.exit(0)\n","\n","signal.signal(signal.SIGALRM, auto_exit)\n","signal.alarm(3*60*60) # 定时关机时间,12小时 x 60分钟 x 60秒 当需要提前关机时可以修改数值"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["if not os.path.exists('sdwui-start-util.ipynb'):\n"," !wget https://huggingface.co/viyi/sdwui/resolve/main/sdwui-start-util.ipynb -o log.log\n","%run sdwui-start-util.ipynb"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["try:\n"," check_gpu() # 检查是否存在gpu\n"," main()\n"," signal.alarm(0)\n","except KeyboardInterrupt:\n"," stop_solo_threads() # 中断后自动停止后台线程 (有部分功能在后台线程中运行)\n"," signal.alarm(0)"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["# 打包收藏文件夹 如果需要可以取消下面两行的注释\n","# zipPath('$install_path/sd_main_dir/log','log')\n","# !mv {output_path}/log.tar {output_path}/log.tar.bak\n","# createOrUpdateDataSet(f'{output_path}/log.tar.bak','sd-webui-log-bak')\n","\n","# 打包 这一行的结果是 压缩一个目录,并放在 output_path: /kaggle/working/ 目录下 名字是训练输出.tar\n","# zipPath('$install_path/sd_main_dir/textual_inversion','训练输出') \n","# zipPath('$install_path/sd_main_dir/outputs','outputs')\n","\n","# 打包venv并上传到数据集\n","# zipPath('$install_path/sd_main_dir/venv','venv')\n","# !mv {output_path}/venv.tar /kaggle/working/venv.tar.bak\n","# createOrUpdateDataSet('/kaggle/working/venv.tar.bak','sd-webui-venv')\n","\n","# 打包命令参考,--exclude 可以排除不需要打包的目录\n","# !tar -cf $output_path/webui.tar.bak --exclude=venv --exclude=extensions -C /sd_main_dir/ ."]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.10.7"}},"nbformat":4,"nbformat_minor":4}
|
|
|
|
|
|
sdwui-before-new.ipynb
DELETED
|
@@ -1 +0,0 @@
|
|
| 1 |
-
{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# NovelAi stable-diffusion-webui+api+sdxl\n---\n**version: 1.6.0 • python: 3.10.6 • torch: 2.0.1+cu118 • xformers: 0.0.21 • gradio: 3.41.2**\n- 发布地址 [kaggle stable-diffusion-webui-novelai](https://www.kaggle.com/code/yiyiooo/stable-diffusion-webui-novelai)\n- 这是一个用于快速体验ai绘画项目 [stable-diffusion-webui](https://github.com/AUTOMATIC1111/stable-diffusion-webui) 的笔记本,你可以直接启动就能在线体验ai绘图的乐趣。 \n- 在保持可以免配置直接启动的情况下也提供了很多可自定义的配置,在下方的配置项里,请自行查看。 \n- 同时也为新人提供了一份基础的帮助文档,包含了一些使用中可能遇到的问题,如果使用过程中有什么疑问,不妨先看看帮助文档。\n- 如果你需要在此脚本上修改再发布,请随意,但请遵守相关法律法规,文明使用。\n- 交流群632428790 这是 [qq2575044704](https://www.kaggle.com/qq2575044704) 的群,感谢他为这个笔记做了一些宣传。\n","metadata":{}},{"cell_type":"markdown","source":"## 重要文件列表\n\n- **这个列表仅加载一次 且会等待加载完成**\n- ```[]```内的是下载文件的目标目录,可以是相对目录也可以是觉得路径\n- ```[]```的下一行就是文件列表,可以是下载地址、git仓库、文件路径、文件夹路径,且支持通配符\n- 如果需要对下载的文件重命名,可以在下载链接前面写上文件名后加一个```:```分开文件名和下载地址\n- 如果需要下载到其他目录,可以使用同样的格式写其他目录","metadata":{}},{"cell_type":"code","source":"重要文件列表 = '''# 这个列表仅加载一次 且会等待加载完成\n[extensions] # 插件\nhttps://github.com/dtlnor/stable-diffusion-webui-localization-zh_CN.git\nhttps://github.com/AlUlkesh/stable-diffusion-webui-images-browser.git\nhttps://github.com/DominikDoom/a1111-sd-webui-tagcomplete.git\nhttps://github.com/Mikubill/sd-webui-controlnet.git\nhttps://github.com/LianZiZhou/sd-webui-pixink-console.git\nhttps://github.com/ilian6806/stable-diffusion-webui-state.git\nhttps://github.com/pkuliyi2015/multidiffusion-upscaler-for-automatic1111.git\nhttps://github.com/Bing-su/adetailer.git\nhttps://github.com/civitai/sd_civitai_extension.git\nhttps://github.com/zanllp/sd-webui-infinite-image-browsing.git\nhttps://github.com/viyiviyi/stable-diffusion-webui-zoomimage.git\n\n# 如果你有模型文件需要在启动前加载,可以写在这个下面对应位置\n\n[models/Stable-diffusion] # 大模型列表\n\n[models/hypernetworks] # hypernetworks文件列表\n\n[models/embeddings] # embeddings文件列表\n\n[models/Lora] # Lora文件列表\n\n[models/VAE] # VAE文件列表\n\n[extensions/sd-webui-controlnet/models] # controlnet插件的模型列表\n\n'''","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 普通文件列表\n\n- **这个列表仅加载一次 且不会等待加载完成**\n- ```[]```内的是下载文件的目标目录,可以是相对目录也可以是觉得路径\n- ```[]```的下一行就是文件列表,可以是下载地址、git仓库、文件路径、文件夹路径,且支持通配符\n- 如果需要对下载的文件重命名,可以在下载链接前面写上文件名后加一个```:```分开文件名和下载地址\n- 如果需要下载到其他目录,可以使用同样的格式写其他目录","metadata":{}},{"cell_type":"code","source":"普通文件列表='''# 这个列表仅加载一次 且不会等待加载完成\n[extensions] # 插件 如果你没有使用ngrok或者frpc,请不要把插件放在这里加载,因为这里的文件可能在webui启动后才加载完成\n\n[models/Stable-diffusion] # 大模型列表\nmg-Tender.safetensors:https://civitai.com/api/download/models/75587\n容华_国风_SDXL.safetensors:https://civitai.com/api/download/models/151978\n\n[models/hypernetworks] # hypernetworks文件列表\n\n[models/embeddings] # embeddings文件列表\n\n[models/Lora] # Lora文件列表\nGenshin_Impact_all-in-one.safetensors:https://civitai.com/api/download/models/116970\nhttps://civitai.com/api/download/models/117151 # Clothing +/- Adjuster 衣物增/减 LoRA\nhttps://civitai.com/api/download/models/62833 # Detail Tweaker LoRA (细节调整LoRA)\n\n[models/VAE] # VAE文件列表\n{input_path}/vae-ft-ema-prunedsafetensors/vae-ft-ema-560000-ema-pruned.safetensors\n{input_path}/vae-ft-ema-prunedsafetensors/vae-ft-mse-840000-ema-pruned.safetensors\nhttps://huggingface.co/stabilityai/sd-vae-ft-ema-original/resolve/main/vae-ft-ema-560000-ema-pruned.safetensors\nhttps://huggingface.co/WarriorMama777/OrangeMixs/resolve/main/VAEs/orangemix.vae.pt\nsdxl_vae.safetensors:https://civitai.com/api/download/models/130720?type=VAE # sdxl模型需要sdxl的vae\n\n[extensions/sd-webui-controlnet/models] # controlnet插件的模型列表\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11e_sd15_ip2p_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11e_sd15_shuffle_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11f1e_sd15_tile_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11f1p_sd15_depth_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_canny_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_inpaint_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_lineart_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_mlsd_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_normalbae_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_openpose_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_scribble_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_seg_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_softedge_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15s2_lineart_anime_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11u_sd15_tile_fp16.safetensors\n'''\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 按顺序加载的重要文件列表\n\n- **这个列表每次 run all 启动都会加载一次,且一定按照顺序加载后才启动webui**\n- ```[]```内的是下载文件的目标目录,可以是相对目录也可以是觉得路径\n- ```[]```的下一行就是文件列表,可以是下载地址、git仓库、文件路径、文件夹路径,且支持通配符\n- 如果需要对下载的文件重命名,可以在下载链接前面写上文件名后加一个```:```分开文件名和下载地址\n- 如果需要下载到其他目录,可以使用同样的格式写其他目录","metadata":{}},{"cell_type":"code","source":"按顺序加载的重要文件列表 = ''' # 这个列表每次 run all 启动都会加载一次,且一定按照顺序加载\n\n# 如果你需要每次启动都加载一下文件,可以写在这。(比如测试路径是否正确的时候)\n\n[models/Stable-diffusion] # 大模型列表\n\n[models/hypernetworks] # hypernetworks文件列表\n\n[models/embeddings] # embeddings文件列表\n\n[models/Lora] # Lora文件列表\n\n[models/VAE] # VAE文件列表\n\n[extensions/sd-webui-controlnet/models] # controlnet插件的模型列表\n\n'''","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## webui 启动参数\n- 所有的参数都会在启动时传入\n- 可以在前面加```#```来屏蔽某个参数\n- 端口参数需要在下一个代码块的```webuiPort```处修改","metadata":{}},{"cell_type":"code","source":"参数列表='''\n# --ckpt=mg-Tender.safetensors # 默认模型名称,路径不能包含空格\n--disable-safe-unpickle \n--deepdanbooru \n--no-hashing \n--no-download-sd-model \n--administrator\n--skip-torch-cuda-test \n--skip-version-check \n--disable-nan-check\n# --opt-sdp-attention \n--opt-sdp-no-mem-attention \n--xformers-flash-attention\n--xformers\n--api \n--listen\n--lowram\n--no-gradio-queue\n--share\n--disable-console-progressbars\n--no-half-vae \n# --no-half #关闭半精度\n# --enable-console-prompts\n# --nowebui\n# --api-auth=2333:6666 # api密码\n# --gradio-auth=2333:6666 # webui密码\n'''","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"useGooglrDrive = True # 连接到谷歌云盘 在google colab环境才会生效\n#Ngrok\nuseNgrok=True # 非必填 是否使用ngrok作为公网访问地址\n#Frpc\nuseFrpc=True # 开启frp将不能启动\n\n#文件或直接填配置\nngrok配置或文件地址='''\n{input_path}/configs/ngrok_token.txt\n'''\nfrp配置文件或配置='''\n{input_path}/configs/frpc_litechat.ini\n'''\nfrpSSL文件='''\n{input_path}/configs/litechat_nginx\n'''\n\n# 配置启动参数\nwebuiPort=7860 # webui默认端口\n\n# 仓库地址 这是修改过界面布局顺序的webui,不定期同步到官方版本\n# 如果要使用官方版本,改成这个: https://github.com/AUTOMATIC1111/stable-diffusion-webui\nwebui_git_repo='https://github.com/viyiviyi/stable-diffusion-webui.git -b local' \n# 配置文件,包括webui的设置和UI默认值,如果要自定义,fork这个仓库后修改并把地址替换这个地址\nwebui_config_git_repu = 'https://github.com/viyiviyi/sd-configs.git'\n# 设置文件保存路径 当使用谷歌云盘时非常有用\nsetting_file = '{output_path}/configs/config.json'\nui_config_file = '{output_path}/configs/ui-config.json'\n\n# 这是配置文件夹同步的相关配置\n# 需要在huggingface创建一个数据集(datasets) 然后把数据集的名称(在页面上有复制的按钮)填到 huggingface_repo \n# 需要获取 token 填到 huggingface_token 获取的地址是: https://huggingface.co/settings/tokens\nhuggingface_token = '{input_path}/configs/huggingface_token.txt'\nhuggingface_repo = 'viyi/sdwui-log'\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"link_instead_of_copy = True # 下载或加载Input的文件时是使用链接还是复制的方式加载到目标目录\nhidden_console_info = True # 是否隐藏大部分的控制台内容","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 保存当前目录和启动时cd到之前保存的目录,可以减少sdwui-start-new.ipynb文件下载次数\nimport os\nINIT_WORK_PATH = os.environ['HOME']\nif os.getenv('INIT_WORK_PATH',''):\n INIT_WORK_PATH = os.getenv('INIT_WORK_PATH','')\nelse:\n os.environ['INIT_WORK_PATH'] = os.getcwd()\n%cd {INIT_WORK_PATH}","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"reLoad = True\n# 如果需要重新安装,请注释下面这一行\nreLoad = False","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not os.path.exists('sdwui-start-new.ipynb'):\n !wget https://huggingface.co/viyi/sdwui/resolve/main/sdwui-start-new.ipynb -o log.log\n%run sdwui-start-new.ipynb","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 打包收藏文件夹 如果需要可以取消下面两行的注释\n# zipPath('$install_path/stable-diffusion-webui/log','log')\n# !mv {output_path}/log.tar {output_path}/log.tar.bak\n# createOrUpdateDataSet(f'{output_path}/log.tar.bak','sd-webui-log-bak')\n\n# 打包 这一行的结果是 压缩一个目录,并放在 output_path: /kaggle/working/ 目录下 名字是训练输出.tar\n# zipPath('$install_path/stable-diffusion-webui/textual_inversion','训练输出') \n# zipPath('$install_path/stable-diffusion-webui/outputs','outputs')\n\n# 打包venv并上传到数据集\n# zipPath('$install_path/stable-diffusion-webui/venv','venv')\n# !mv {output_path}/venv.tar /kaggle/working/venv.tar.bak\n# createOrUpdateDataSet('/kaggle/working/venv.tar.bak','sd-webui-venv')\n\n# 打包命令参考,--exclude 可以排除不需要打包的目录\n# !tar -cf $output_path/webui.tar.bak --exclude=venv --exclude=extensions -C /kaggle/stable-diffusion-webui/ .","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 使用帮助\n---\n**代码块不能删除也不能调换顺序,如果出现变量未定义,请检查是否按顺序执行了代码块**\n\n---\n\n## kaggle账号\n- 注册账号需要手机号,国内手机号也行,如果点击注册后没反应,估计是需要梯子,用于人机验证\n- 注册后点此笔记的 **Copy & Edit** 按钮就进到编辑界面\n\n## 准备工作\n1. 右侧面板 **Notebook options/ACCELERATOR** 需要选择GPU **T4x2**出图更快\n2. 右侧面板 **Notebook options/LANGUAGE** 需要选择Python\n2. 右侧面板 **Notebook options/PERSISTENCE** 建议选择 Files only **作用是保存Outpot目录内的文件,当前这个功能并没有任何作用**\n3. 右侧面板 **Notebook options/ENVIRONMENT** 建议不改这个配置,使用当前默认值就行\n4. 右侧面板 **Notebook options/INTERNET** 需要打开 用于联网\n\n## 启动\n#### 启动方式一 **直接点击页面上边的 RunAll**\n- 手机端可能会出现页面上边的工具栏不显示的情况,左侧菜单按钮里也有相关的操作\n- 长时间不操作页面会导致脚本停止 (应该是40分钟吧)\n\n#### 启动方式二 **使用页面上边的 Save Version 后台运行**\n- 后台运行不用担心长时间不操作脚本停止\n- Version Type 选择 **Save & Run All**\n- 在Save Version弹窗里需要选择使用**GPU**环境 (Advanced Settings 里最后一个选项)\n\n## 访问\n- 如果你使用了ngrok或者frpc,可以访问你这两对应的地址\n- 如果你不知道你的ngrok或者frpc的地址可以在控制台(页面最下方Console)的输出里面查看\n- 使用Run All方式启动,控制台在启动完成后会输出访问网址,网址内容包含**gradio.live**,可以在页面中搜索快速找到\n- 如果使用Save Verson的方式启动,点击左下角的**View Active Events**点击刚刚启动的脚步,在**Log**里找访问网址\n- 一般情况下第一次启动此脚本需要等待kaggle下载模型文件,进度在页面上方\n- 第二次及以后(不增加新的文件)需要3到5分钟\n\n## 增加模型\n- 可以直接写模型的下载链接,省去下面这些步骤\n1. 先创建数据集,也就是dataset\n2. 创建时需要添加文件,选择自己的模型文件就行\n3. 同类型文件放相同的数据集里面,一个数据集也不要太大\n4. 可以在dataset搜索其他人上传的模型\n5. 通过右侧的 **Add Data** 按钮选择已经上传的模型文件或者别人上传的模型文件\n - input 下面的列表就是模型文件,可以点击名称后面的复制按钮复制路径\n6. 将模型路径放在配置里的对应配置里即可,支持文件夹和文件路径,参考 **modelDirs**\n - 如果目录里还有子目录也是需要加载的,可以用*表示子目录 例子:比如Loras目录下还有角色、画风、涩涩的文件夹,那路径里写成 '/kaggle/input/Loras/*'就可以加载子目录里面的文件了\n - 模型加载使用的文件链接方式,如果你融模型的时候新模型名字和原有模型名字一样,会出现不能修改只读文件的错误\n - 同理,直接对模型做编辑的工具可能也会出现相同的错误\n \n \n- **受到kaggle内存大小的影响,切换多个模型后大概率爆内存导致停止运行**\n \n**下边的配置项都写了对应配置的作用和使用说明,不理解的话也不用改,用默认的就好**\n\n## 下载文件\n#### 方式一\n- 在浏览器直接下 比如你需要下载的文件路径在 /kaggle/stable-diffusion-webui/models/Lora/dow_a.safetensors\n - 比如你需要下载的文件路径在 /kaggle/stable-diffusion-webui/models/Lora/dow_a.safetensors\n - 你的访问地址是 https://123123123.gradio.live\n - 则可以在浏览器输入 https://123123123.gradio.live/file=/kaggle/stable-diffusion-webui/models/Lora/dow_a.safetensors 下载你的文件\n \n#### 方式二\n- 复制到Output目录下载 仅支持使用Run All方式运行的\n - 比如你需要下载的文件路径在 /kaggle/stable-diffusion-webui/models/Lora/dow_a.safetensors\n - 先停止笔记本(不是关机,是停止)\n - 然后新建一个代码块,在里面输入 !cp -f /kaggle/stable-diffusion-webui/models/Lora/dow_a.safetensors /kaggle/working/\n - 或者 新建一个代码块,在里面输入 !cp -f \\$install_path/stable-diffusion-webui/models/Lora/dow_a.safetensors /kaggle/working/\n - 你可能需要拼接路径 如果是在webui里面看到的路径,且路径里面没有带**stable-diffusion-webui**\n - 拼接方式是 **\\$install_path/stable-diffusion-webui** + **文件路径** 拼成类似前一条的样子\n - 就可以在右侧列表的Output目录看见复制出来的文件,点击下载即可\n\n## **一些可能没用的说明**\n- 配置说明 **True或者False**表示布尔值 **True**表示“**是**” **False**表示“**否**” 只有这两个值\n- 配置说明 **[]** 表示数组,里面可以存放内容,每个内容需要用**英语(半角)逗号**隔开\n- 配置说明 **''或者\"\"** 英语(半角)的双引号或者单引号包裹的内容是**字符串**,比如放在数组里面的路径就需要是一个字符串\n- 配置说明 **#** **#** 后面的内容是**注释**,是帮助性内容,对整个代码的执行不会有影响\n","metadata":{}},{"cell_type":"markdown","source":"# 更新记录\n#### 230910 v175\n- 增加了默认的sdxl模型\n- 修改了不合适的使用说明\n\n#### 230901 v173\n- 更新了依赖版本,可以加载sdxl模型了\n- 增加代码块内容说明,希望有用\n\n#### 230812 v171\n- 把关闭半精度的参数注释了,这是之前写错的,注释后不容易爆内存\n- 增加默认模型的参数,用于指定模型启动时默认的模型\n\n#### 230726 v170\n- 更新了整个配置,可以更加自由的下载和加载文件\n- 删除了大部分参数\n\n#### 230726 v169\n- 增加了一个文件加载配置,可以自定义把文件或下载地址加载到指定目录,配置方式见 [ 其他文件列表 ]\n- 增加了一个配置,可以隐藏部分控制台输出,但隐藏不完全,没啥用\n\n#### 230719 v168\n- 增加了同步收藏文件夹到 huggingface 数据集的功能,仅同步收藏文件夹,如果同步所有图片也太浪费资源了\n\n#### 230716 v167\n- 账号解封了\n- 已经更新为精简自动更新版,主要逻辑分离存放到 [huggingface](https://huggingface.co/viyi/sdwui),这边基本上不再需要更新\n- 如果增加了新功能需要��的配置,可以在输出内容的最前面查看到(暂定)\n\n#### 230302 v165\n- 可以修改disableShared=True来使用pm2启动,做到爆内存自动重启(需要使用frpc或者ngrok代理,否则无法访问界面)\n\n#### 230228 v156\n- 移除了koishi的相关功能 如需使用,可查看 [sd-webui-koishi](https://www.kaggle.com/code/yiyiooo/sd-webui-koishi)\n\n#### 230227 v147\n- 增加了nginx做反向代理,现在可以使用一个ngrok地址访问多个服务了 功能在版本156移除\n\n#### 230225 v139\n- 可以加载ssl证书,启动https的隧道了\n\n#### 230224 v134\n- 可以自动修改frp的本地端口\n\n#### 230224 v128\n- 修复默认模型文件不存在时不能启动的问题\n- 修复了多线程导致依赖等内容安装位置错乱的问题\n- 修复了第一次启动会更新koishi数据对应的数据集问题\n- 增加了配置检查功能,对一些配置项做了提示\n- 增加了可配置webui端口功能,现在可以配置webui、froc、ngrok的端口了\n\n#### 230223 v126\n- 修复了仅适用koishi数据目录无法启动koishi的问题\n- 修改了部分文档\n\n#### 230223 v124\n- 修复使用多线程后出现的文件安装下载目录失败的问题\n- 修复使用多线程后文件目录错乱问题\n\n#### 230222 v123\n- 使用多线程进行安装,节省安装时间\n\n#### 230222 v122\n- 更改了默认配置,现在训练的输出可以在Output下面查看了\n\n#### 230222 v118\n- 增加了自动上传koishi的数据到数据集且能自动下载的功能\n - 自动上传的数据集优先级高于手动上传的\n - 上一个版本的数据集与当前版本的目录结构有差异,如果更新后需要修改配置\n \n#### 230121 v111\n- 增加了koishi的部署相关功能 功能在版本156移除\n\n#### 230220 v110\n- 增加了ControlNet插件的一些说明\n\n#### 230220 v109\n- 修复第二次Run all时不能切换到新的frpc配置问题\n- 增加更新记录,用于记录每次更新 ","metadata":{}}]}
|
|
|
|
|
|
sdwui-before.ipynb
CHANGED
|
@@ -1 +1 @@
|
|
| 1 |
-
{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.7.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# NovelAi stable-diffusion-webui+api\n---\n**env版本: torch: 2.0+cu117 • xformers: 0.0.19**\n- 发布地址 [kaggle stable-diffusion-webui-novelai](https://www.kaggle.com/code/yiyiooo/stable-diffusion-webui-novelai)\n- 这是一个用于快速体验ai绘画项目 [stable-diffusion-webui](https://github.com/AUTOMATIC1111/stable-diffusion-webui) 的笔记本,你可以直接启动就能在线体验ai绘图的乐趣。 \n- 在保持可以免配置直接启动的情况下也提供了很多可自定义的配置,在下方的配置项里,请自行查看。 \n- 同时也为新人提供了一份基础的帮助文档,包含了一些使用中可能遇到的问题,如果使用过程中有什么疑问,不妨先看看帮助文档。\n- 如果你需要在此脚本上修改再发布,请随意,但请遵守相关法律法规,文明使用。\n- 交流群632428790 这是 [qq2575044704](https://www.kaggle.com/qq2575044704) 的群,感谢他为这个笔记做了一些宣传。\n","metadata":{}},{"cell_type":"markdown","source":"# 发布账号已经更换,这边不在更新了 [新地址](https://www.kaggle.com/code/yiyiooo/stable-diffusion-webui-novelai)","metadata":{}},{"cell_type":"code","source":"useGooglrDrive = True # 连接到谷歌云盘 在google colab环境才能开启","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 模型列表 一行一个 可以填文件 文件夹 和下载地址,如果需要自定义文件名,在url前写上文件名加:\n模型列表 = '''\nmg-Tender.safetensors:https://civitai.com/api/download/models/75587\n'''\n# 启动时默认加载的模型名称\nusedCkpt = 'mg-Tender'\nVAE列表 = '''\nhttps://huggingface.co/stabilityai/sd-vae-ft-ema-original/resolve/main/vae-ft-ema-560000-ema-pruned.safetensors\nhttps://huggingface.co/stabilityai/sd-vae-ft-mse-original/resolve/main/vae-ft-mse-840000-ema-pruned.safetensors\nhttps://huggingface.co/WarriorMama777/OrangeMixs/resolve/main/VAEs/orangemix.vae.pt\n'''\n\nLora列表 = '''\nGenshin_Impact_all-in-one.safetensors:https://civitai.com/api/download/models/116970\nhttps://civitai.com/api/download/models/14856\n'''\n\nLyCORIS列表 = '''\nhttps://civitai.com/api/download/models/46821\n'''\n\nhypernetworks列表 = '''\n\n'''\n\nembeddings列表 = '''\n\n'''\n\ncontrolNet模型列表 = '''\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11e_sd15_ip2p_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11e_sd15_shuffle_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11f1e_sd15_tile_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11f1p_sd15_depth_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_canny_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_inpaint_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_lineart_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_mlsd_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_normalbae_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_openpose_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_scribble_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_seg_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_softedge_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15s2_lineart_anime_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11u_sd15_tile_fp16.safetensors\n'''\n# git仓库\n插件列表='''\nhttps://github.com/dtlnor/stable-diffusion-webui-localization-zh_CN.git\nhttps://github.com/AlUlkesh/stable-diffusion-webui-images-browser.git\nhttps://github.com/DominikDoom/a1111-sd-webui-tagcomplete.git\nhttps://github.com/Mikubill/sd-webui-controlnet.git\nhttps://github.com/KohakuBlueleaf/a1111-sd-webui-lycoris.git\nhttps://github.com/ilian6806/stable-diffusion-webui-state.git\nhttps://github.com/pkuliyi2015/multidiffusion-upscaler-for-automatic1111.git\nhttps://github.com/Bing-su/adetailer.git\nhttps://github.com/viyiviyi/prompts-filter.git # 这个插件会过滤空tag,如果不需要,请删除\nhttps://github.com/zanllp/sd-webui-infinite-image-browsing.git\nhttps://github.com/viyiviyi/stable-diffusion-webui-zoomimage.git\n'''\n#文件或直接填配置\nngrok配置或文件地址='''\n$input_path/configs/ngrok_token.txt\n'''\n\nfrp配置文件或配置='''\n-f **************************:7691619\n'''\n\nfrpSSL文件='''\n\n'''\n\n参数列表='''\n--disable-safe-unpickle \n--deepdanbooru \n--no-hashing \n--no-download-sd-model \n--administrator\n--skip-torch-cuda-test \n--skip-version-check \n--disable-nan-check\n--opt-sdp-attention \n--opt-sdp-no-mem-attention \n--xformers-flash-attention\n--xformers\n--api \n--listen\n--lowram\n--no-gradio-queue\n'''\n\n# --api-auth=2333:6666 --gradio-auth=2333:6666","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 手机端界面优化 使用了修改过界面布局顺序的webui,不定期同步到官方版本\nmobileOptimize=True\n# webui的配置文件\nwebui_settings = 'https://github.com/viyiviyi/sd-configs.git'\n# 设置文件路径\nsetting_file = '/kaggle/working/configs/config.json'\nui_config_file = '/kaggle/working/configs/ui-config.json'\n\n# 配置启动参数\nwebuiPort=7860 # webui默认端口\ndisableShared=False # 关闭默认的gradio.live穿透\nonlyApi=False # 无ui界面,仅提供api服务\nquickStart=True # 快速启动 使用下载好的python环境 开启后启动到可用需要4分钟,不开启需要8分钟\nvaeHalf=False # vae开启半精度,关闭效果更好,对速度没啥影响\nmodelHalf=True # 模型开启半精度,关闭效果更好,但生成速度减半\nconsoleProgressbars=False # 控制台显示进度条,关闭可以减少一些输出内容,查看日志时更快一点\nconsolePrompts=False # 同上 \nenableLoadByCopy=False # 是否使用copy的方式加载文件 启动变慢,且测试后没有提高模型切换速度\nenableThread=True # 启用多线程下载插件 依赖 和 模型\n#Ngrok\nuseNgrok=True # 非必填 是否使用ngrok作为公网访问地址\n#Frpc\nuseFrpc=True # 开启frp将不能启动\n\nimport os\nINIT_WORK_PATH = os.environ['HOME']\nif os.getenv('INIT_WORK_PATH',''):\n INIT_WORK_PATH = os.getenv('INIT_WORK_PATH','')\nelse:\n os.environ['INIT_WORK_PATH'] = os.getcwd()\n%cd {INIT_WORK_PATH}","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 这是配置文件夹同步的相关配置\n# 需要在huggingface创建一个数据集(datasets) 然后把数据集的名称(在页面上有复制的按钮)填到 huggingface_repo \n# 需要获取 token 填到 huggingface_token 获取的地址是: https://huggingface.co/settings/tokens\n# 填了huggingface_token这个值的就不要在任何地方分享你的笔记,否则得到你的token的人可以随意的访问你的 huggingface 账号\n# 也可以填写一个存放了token的文件的目录,这样就能规避风险\nhuggingface_token = '{input_path}/configs/huggingface_token.txt'\nhuggingface_repo = 'viyi/sdwui-log'","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"reLoad = True\n# 如果需要重新安装,请注释这一行\nreLoad = False","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!wget https://huggingface.co/viyi/sdwui/resolve/main/sdwui-start.ipynb\n%run sdwui-start.ipynb","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n# 打包收藏文件夹 如果需要可以取消下面两行的注释\n# zipPath('$install_path/stable-diffusion-webui/log','log')\n# !mv {output_path}/log.tar {output_path}/log.tar.bak\n# createOrUpdateDataSet(f'{output_path}/log.tar.bak','sd-webui-log-bak')\n\n# 打包 这一行的结果是 压缩一个目录,并放在 output_path: /kaggle/working/ 目录下 名字是训练输出.tar\n# zipPath('$install_path/stable-diffusion-webui/textual_inversion','训练输出') \n# zipPath('$install_path/stable-diffusion-webui/outputs','outputs')\n# zipPath('$install_path/stable-diffusion-webui/venv','venv')\n# !mv {output_path}/venv.tar /kaggle/working/venv.tar.bak\n# createOrUpdateDataSet('/kaggle/working/venv.tar.bak','sd-webui-venv')\n# !tar -cf $output_path/webui.tar.bak --exclude=venv --exclude=extensions -C /kaggle/stable-diffusion-webui/ .","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 使用帮助\n---\n**代码块不能删除也不能调换顺序,如果出现变量未定义,请检查是否按顺序执行了代码块**\n\n---\n\n## kaggle账号\n- 注册账号需要手机号,国内手机号也行,如果点击注册后没反应,估计是需要梯子,用于人机验证\n- 注册后点此笔记的 **Copy & Edit** 按钮就进到编辑界面\n\n## 准备工作\n1. 右侧面板 **Settings/ACCELERATOR** 需要选择GPU **T4x2**出图���快,且会自动开启两个webui\n2. 右侧面板 **Settings/LANGUAGE** 需要选择Python\n2. 右侧面板 **Settings/PERSISTENCE** 建议选择 Files only **作用是保存Outpot目录内的文件**\n3. 右侧面板 **Settings/ENVIRONMENT** 建议不改这个配置,使用当前默认值就行\n4. 右侧面板 **Settings/INTERNET** 需要打开 用于联网,没网跑不起来的啊\n\n## 启动\n#### 启动方式一 **直接点击页面上边的 RunAll**\n- 在没有关闭电源的情况下,后几次点击RunAll的输出在页面上端 (其实没有必要了,之前不知道代码块可以收起,很烦滚动到页面底端才能看见输出)\n- 手机端可能会出现页面上边的工具栏不显示的情况,左侧菜单按钮里也有相关的操作\n- 长时间不操作页面会导致脚本停止 (应该是40分钟吧)\n\n#### 启动方式二 **使用页面上边的 Save Version 后台运行**\n- 后台运行不用担心长时间不操作脚本停止\n- Version Type 选择 **Save & Run All**\n- 在Save Version弹窗里需要选择使用**GPU**环境 (Advanced Settings 里最后一个选项)\n- 后台运行的输出的图片可以在运行结束后下载(但是保存时间有限制,我就经常下不到,不够问题不大,喜欢的图在生成后就下载了)\n- 如果你需要下载运行后的图片,请不要把安装目录修改到 /kaggle/working 这个目录下,因为没有写打包功能,下载只能下载整个输出目录,也就是 /kaggle/working 目录\n\n## 访问\n- 如果你使用了ngrok或者frpc,可以访问你这两对应的地址\n- 如果你不知道你的ngrok或者frpc的地址可以在控制台(页面最下方Console)的输出里面查看\n- 使用Run All方式启动,控制台在启动完成后会输出访问网址,网址内容包含**gradio.live**,可以在页面中搜索快速找到\n- 如果使用Save Verson的方式启动,点击左下角的**View Active Events**点击刚刚启动的脚步,在**Log**里找访问网址\n- 一般情况下第一次启动此脚本需要等待kaggle下载模型文件,进度在页面上方\n- 第二次及以后(不增加新的文件)需要3到5分钟\n\n## 增加模型\n1. 先创建数据集,也就是dataset\n2. 创建时需要添加文件,选择自己的模型文件就行\n3. 同类型文件放相同的数据集里面,一个数据集也不要太大\n4. 可以在dataset搜索其他人上传的模型\n5. 通过右侧的 **Add Data** 按钮选择已经上传的模型文件或者别人上传的模型文件\n - input 下面的列表就是模型文件,可以点击名称后面的复制按钮复制路径\n6. 将模型路径放在配置里的对应配置里即可,支持文件夹和文件路径,参考 **modelDirs**\n - 如果目录里还有子目录也是需要加载的,可以用*表示子目录 例子:比如Loras目录下还有角色、画风、涩涩的文件夹,那路径里写成 '/kaggle/input/Loras/*'就可以加载子目录里面的文件了\n - 模型加载使用的文件链接方式,如果你融模型的时候新模型名字和原有模型名字一样,会出现不能修改只读文件的错误\n - 同理,直接对模型做编辑的工具可能也会出现相同的错误\n \n \n- **为了提高启动速度,导致切换模型过程较慢,点击切换模型后进度条大概率会一直存在,但模型在1分半左右基本能加载完。** \n- **受到kaggle内存大小的影响,切换多个模型后大概率爆内存导致停止运行**\n \n**下边的配置项都写了对应配置的作用和使用说明,不理解的话也不用改,用默认的就好**\n\n## 下载文件\n#### 方式一\n- 在浏览器直接下 比如你需要下载的文件路径在 /kaggle/stable-diffusion-webui/models/Lora/dow_a.safetensors\n - 比如你需要下载的文件路径在 /kaggle/stable-diffusion-webui/models/Lora/dow_a.safetensors\n - 你的访问地址是 https://123123123.gradio.live\n - 则可以在浏览器输入 https://123123123.gradio.live/file=/kaggle/stable-diffusion-webui/models/Lora/dow_a.safetensors 下载你的文件\n \n#### 方式二\n- 复制到Output目录下载 仅支持使用Run All方式运行的\n - 比如你需要下载的文件路径在 /kaggle/stable-diffusion-webui/models/Lora/dow_a.safetensors\n - 先停止笔记本(不是关机,是停止)\n - 然后新建一个代码块,在里面输入 !cp -f /kaggle/stable-diffusion-webui/models/Lora/dow_a.safetensors /kaggle/working/\n - 或者 新建一个代码块,在里面输入 !cp -f \\$install_path/stable-diffusion-webui/models/Lora/dow_a.safetensors /kaggle/working/\n - 你可能需要拼接路径 如果是在webui里面看到的路径,且路径里面没有带**stable-diffusion-webui**\n - 拼接方式是 **\\$install_path/stable-diffusion-webui** + **文件路径** 拼成类似前一条的样子\n - 就可以在右侧列表的Output目录看见复制出来的文件,点击下载即可\n \n#### 方式三\n- 开启链接输出目录的配置 (配置在第二个代码块,通过搜索**配置文件链接**快速查找)\n - 此方法会把已知的三个训练输出目录链接到Output目录下,直接去下载即可(两种启动方式都可以用)\n - 如果有新的目录需要链接,可以参考着自己写或者联系我\n \n#### 方式四\n- 将安装目录改到输出目录(配置在第二个代码块,通过搜索**安装目录**快速查找)\n - 此方式会把所有文件都放在安装目录,找到并下载即可\n - 如果使用这个方式,右侧的设置里**PERSISTENCE**这个设置项建议选No pensistence。如果选其他项,可能会出现关机特别慢的情况,因为需要上传输出目录的文件。\n\n## **一些可能没用的说明**\n- 配置说明 **True或者False**表示布尔值 **True**表示“**是**” **False**表示“**否**” 只有这两个值\n- 配置说明 **[]** 表示数组,里面可以存放内容,每个内容需要用**英语(半角)逗号**隔开\n- 配置说明 **''或者\"\"** 英语(半角)的双引号或者单引号包裹的内容是**字符串**,比如放在数组里面的路径就需要是一个字符串\n- 配置说明 **#** **#** 后面的内容是**注释**,是帮助性内容,对整个代码的执行不会有影响\n","metadata":{}},{"cell_type":"markdown","source":"# 更新记录\n#### 230719 v168\n- 增加了同步收藏文件夹到 huggingface 数据集的功能,仅同步收藏文件夹,如果同步所有图片也太浪费资源了\n\n#### 230716 v167\n- 账号解封了\n- 已经更新为精简自动更新版,主要逻辑分离存放到 [huggingface](https://huggingface.co/viyi/sdwui),这边基本上不再需要更新\n- 如果增加了新功能需要新的配置,可以在输出内容的最前面查看到(暂定)\n\n#### 230302 v165\n- 可以修改disableShared=True来使用pm2启动,做到爆内存自动重启(需要使用frpc或者ngrok代理,否则无法访问界面)\n\n#### 230228 v156\n- 移除了koishi的相关功能 如需使用,可查看 [sd-webui-koishi](https://www.kaggle.com/code/yiyiooo/sd-webui-koishi)\n\n#### 230227 v147\n- 增加了nginx做反向代理,现在可以使用一个ngrok地址访问多个服务了 功能在版本156移除\n\n#### 230225 v139\n- 可以加载ssl证书,启动https的隧道了\n\n#### 230224 v134\n- 可以自动修改frp的本地端口\n\n#### 230224 v128\n- 修复默认模型文件不存在时不能启动的问题\n- 修复了多线程导致依赖等内容安装位置错乱的问题\n- 修复了第一次启动会更新koishi数据对应的数据集问题\n- 增加了配置检查功能,对一些配置项做了提示\n- 增加了可配置webui端口功能,现在可以配置webui、froc、ngrok的端口了\n\n#### 230223 v126\n- 修复了仅适用koishi数据目录无法启动koishi的问题\n- 修改了部分文档\n\n#### 230223 v124\n- 修复使用多线程后出现的文件安装下载目录失败的问题\n- 修复使用多线程后文件目录错乱问题\n\n#### 230222 v123\n- 使用多线程进行安装,节省安装时间\n\n#### 230222 v122\n- 更改了默认配置,现在训练的输出可以在Output下面查看了\n\n#### 230222 v118\n- 增加了自动上传koishi的数据到数据集且能自动下载的功能\n - 自动上传的数据集优先级高于手动上传的\n - 上一个版本的数据集与当前版本的目录结构有差异,如果更新后需要修改配置\n \n#### 230121 v111\n- 增加了koishi的部署相关功能 功能在版本156移除\n\n#### 230220 v110\n- 增加了ControlNet插件的一些说明\n\n#### 230220 v109\n- 修复第二次Run all时不能切换到新的frpc配置问题\n- 增加更新记录,用于记录每次更新 ","metadata":{}}]}
|
|
|
|
| 1 |
+
{"cells":[{"cell_type":"markdown","metadata":{"id":"TcLs4cdaLCtB"},"source":["# 配置项 (修改这里的内容后直接启动就行了 run all 或者save version都可以)\n","\n","---\n","\n","**主要逻辑已经分离出去了,当有更新时也不需要更新这个文件**\n","- 所有的模型列表都支持填文件、文件夹、下载地址\n","- **如果需要在google colab运行**\n"," 1. 改好这个文件后下载下来\n"," 2. 在cloab新建一个脚本,然后上传这个文件\n"," 3. 新建单元格后填入```%run sdwui-before.ipynb```,然后直接执行新建的单元格。注意: sdwui-before.ipynb 需要替换成你上传时的文件名"]},{"cell_type":"code","execution_count":null,"metadata":{"id":"swzyZ1_gLCs_","trusted":true},"outputs":[],"source":["useGooglrDrive = True # 连接到谷歌云盘 在google colab环境才能开启"]},{"cell_type":"code","execution_count":null,"metadata":{"id":"7tTWVxHDLCtB","trusted":true},"outputs":[],"source":["# 模型列表 一行一个 可以填文件 文件夹 和下载地址,如果需要自定义文件名,在url前写上文件名加:\n","模型列表 = '''\n","https://civitai.com/api/download/models/75587\n","'''\n","# 启动时默认加载的模型名称\n","usedCkpt = 'mg-Tender'\n","VAE列表 = '''\n","https://huggingface.co/stabilityai/sd-vae-ft-ema-original/resolve/main/vae-ft-ema-560000-ema-pruned.safetensors\n","https://huggingface.co/stabilityai/sd-vae-ft-mse-original/resolve/main/vae-ft-mse-840000-ema-pruned.safetensors\n","https://huggingface.co/WarriorMama777/OrangeMixs/resolve/main/VAEs/orangemix.vae.pt\n","'''\n","Lora列表 = '''\n","https://civitai.com/api/download/models/14856\n","'''\n","LyCORIS列表 = '''\n","https://civitai.com/api/download/models/46821\n","'''\n","hypernetworks列表 = '''\n","\n","'''\n","embeddings列表 = '''\n","\n","'''\n","controlNet模型列表 = '''\n","https://huggingface.co/webui/ControlNet-modules-safetensors/resolve/main/control_canny-fp16.safetensors\n","https://huggingface.co/webui/ControlNet-modules-safetensors/resolve/main/control_depth-fp16.safetensors\n","https://huggingface.co/webui/ControlNet-modules-safetensors/resolve/main/control_hed-fp16.safetensors\n","https://huggingface.co/webui/ControlNet-modules-safetensors/resolve/main/control_mlsd-fp16.safetensors\n","https://huggingface.co/webui/ControlNet-modules-safetensors/resolve/main/control_normal-fp16.safetensors\n","https://huggingface.co/webui/ControlNet-modules-safetensors/resolve/main/control_openpose-fp16.safetensors\n","https://huggingface.co/webui/ControlNet-modules-safetensors/resolve/main/control_scribble-fp16.safetensors\n","https://huggingface.co/webui/ControlNet-modules-safetensors/resolve/main/control_seg-fp16.safetensors\n","'''\n","# git仓库\n","插件列表='''\n","https://github.com/dtlnor/stable-diffusion-webui-localization-zh_CN.git\n","https://github.com/AlUlkesh/stable-diffusion-webui-images-browser.git\n","https://github.com/DominikDoom/a1111-sd-webui-tagcomplete.git\n","https://github.com/Mikubill/sd-webui-controlnet.git\n","https://github.com/KohakuBlueleaf/a1111-sd-webui-lycoris.git\n","https://github.com/LianZiZhou/sd-webui-pixink-console.git\n","https://github.com/ilian6806/stable-diffusion-webui-state.git\n","https://github.com/pkuliyi2015/multidiffusion-upscaler-for-automatic1111.git\n","https://github.com/Bing-su/adetailer.git\n","https://github.com/viyiviyi/filter-empty-prompts.git\n","https://github.com/civitai/sd_civitai_extension.git\n","https://github.com/zanllp/sd-webui-infinite-image-browsing.git\n","'''\n","#文件或直接填配置\n","ngrok配置或文件地址='''\n","/kaggle/input/configs/ngrok_token.txt\n","'''\n","frp配置文件或配置='''\n","-f **************************:7691619\n","'''\n","frpSSL文件='''\n","\n","'''\n","参数列表='''\n","--disable-safe-unpickle \n","--deepdanbooru \n","--no-hashing \n","--no-download-sd-model \n","--administrator\n","--skip-torch-cuda-test \n","--skip-version-check \n","--disable-nan-check\n","--opt-sdp-attention \n","--opt-sdp-no-mem-attention \n","--xformers-flash-attention\n","--xformers\n","--api \n","--listen\n","--lowram\n","--no-gradio-queue\n","'''\n","# --api-auth=2333:6666 --gradio-auth=2333:6666"]},{"cell_type":"code","execution_count":null,"metadata":{"_kg_hide-input":false,"id":"r_lBDJdOLCtB","trusted":true},"outputs":[],"source":["# 手机端界面优化 使用了修改过界面布局顺序的webui,不定期同步到官方版本\n","mobileOptimize=True\n","# webui的配置文件\n","webui_settings = 'https://github.com/viyiviyi/sd-configs.git'\n","# 设置文件路径\n","setting_file = '/kaggle/working/configs/config.json'\n","ui_config_file = '/kaggle/working/configs/ui-config.json'\n","\n","# 配置启动参数\n","webuiPort=7860 # webui默认端口\n","disableShared=False # 关闭默认的gradio.live穿透\n","onlyApi=False # 无ui界面,仅提供api服务\n","quickStart=True # 快速启动 使用下载好的python环境 开启后启动到可用需要4分钟,不开启需要8分钟\n","vaeHalf=False # vae开启半精度,关闭效果更好,对速度没啥影响\n","modelHalf=True # 模型开启半精度,关闭效果更好,但生成速度减半\n","consoleProgressbars=False # 控制台显示进度条,关闭可以减少一些输出内容,查看日志时更快一点\n","consolePrompts=False # 同上 \n","enableLoadByCopy=False # 是否使用copy的方式加载文件 启动变慢,且测试后没有提高模型切换速度\n","enableThread=True # 启用多线程下载插件 依赖 和 模型\n","#Ngrok\n","useNgrok=True # 非必填 是否使用ngrok作为公网访问地址\n","#Frpc\n","useFrpc=True # 开启frp将不能启动\n","\n","import os\n","INIT_WORK_PATH = os.environ['HOME']\n","if os.getenv('INIT_WORK_PATH',''):\n"," INIT_WORK_PATH = os.getenv('INIT_WORK_PATH','')\n","else:\n"," os.environ['INIT_WORK_PATH'] = os.getcwd()\n","%cd {INIT_WORK_PATH}"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["reLoad = True\n","# 如果需要重新安装,请注释这一行\n","reLoad = False"]},{"cell_type":"code","execution_count":null,"metadata":{"scrolled":true,"trusted":true},"outputs":[],"source":["!wget https://huggingface.co/viyi/sdwui/resolve/main/sdwui-start.ipynb\n","%run sdwui-start.ipynb"]},{"cell_type":"code","execution_count":null,"metadata":{"id":"ePT_b-s9LCtF","scrolled":true,"trusted":true},"outputs":[],"source":["\n","# 打包收藏文件夹 如果需要可以取消下面两行的注释\n","# zipPath('$install_path/stable-diffusion-webui/log','log')\n","# !mv {output_path}/log.tar {output_path}/log.tar.bak\n","# createOrUpdateDataSet(f'{output_path}/log.tar.bak','sd-webui-log-bak')\n","\n","# 打包 这一行的结果是 压缩一个目录,并放在 output_path: /kaggle/working/ 目录下 名字是训练输出.tar\n","# zipPath('$install_path/stable-diffusion-webui/textual_inversion','训练输出') \n","# zipPath('$install_path/stable-diffusion-webui/outputs','outputs')\n","# zipPath('$install_path/stable-diffusion-webui/venv','venv')\n","# !mv {output_path}/venv.tar /kaggle/working/venv.tar.bak\n","# createOrUpdateDataSet('/kaggle/working/venv.tar.bak','sd-webui-venv')\n","# !tar -cf $output_path/webui.tar.bak --exclude=venv --exclude=extensions -C /kaggle/stable-diffusion-webui/ ."]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.7.12"}},"nbformat":4,"nbformat_minor":4}
|
sdwui-start-new.ipynb
DELETED
|
@@ -1 +0,0 @@
|
|
| 1 |
-
{"cells":[{"cell_type":"markdown","metadata":{"id":"6zE2QeUKLCtC"},"source":["# 这只是一个完整项目的一部分 不能运行的 \n","- 可以从这个地址运行 [点击打开](https://www.kaggle.com/viyiviyi/sdwui-before)\n","---"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":[]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["update_desc = '''\n","欢迎使用 stable-diffusion-webui 便捷启动脚本\n","\n","此脚本理论上可以在任何jupyter环境运行,但仅在 google colab 和 kaggle 测试。\n","此脚本的【前置脚本】发布地址 https://www.kaggle.com/code/yiyiooo/stable-diffusion-webui-novelai。\n","此脚本需配合 【前置脚本】 的脚本附带的配置项才能正常启动。\n","此脚本的内容会自动更新,你无需更新【前置脚本】就能获取到最新的功能。\n","如果新功能需要增加新的配置项,可以在更新日志中查看到。\n","\n","路径说明\n","* 为了解决平台差异,所有的安装目录和文件输出目录都被重新指定,如果你需要在配置中访问这些目录,请查看以下说明\n","*\n","* 如果链接了谷歌云盘,将会在云盘根目录创建 sdwebui 的文件夹,文件夹内的 Input 目录将会作为 输入目录; Output 将会作为输出目录\n","* 可以使用 $install_path 或 {install_path} 来访问安装目录,写在字符串内也会生效\n","* 项目跟目录固定是: {install_path}/sd_main_dir 或 $install_path/sd_main_dir\n","* $output_path 或 {output_path} 可以访问输出目录\n","* $input_path 或 {input_path} 可以访问输入目录 在kaggle是数据集根目录\n","\n","更新日志\n","* 23-09-13\n","* 修改了项目安装目录的文件夹名称,改为sd_main_dir,访问方式是{install_path}/sd_main_dir\n","*\n","* 23-08-02\n","* 需要增加配置 [多实例 = True] 来使用第二张显卡\n","*\n","* 23-08-01\n","* 估计是新的gradio的问题,需要禁用 --no-gradio-queue 启动参数才能正常访问,否则会一直处于加载界面,所以这个参数会被屏蔽不再生效\n","*\n","* 23-07-30\n","* 使用新的文件加载逻辑重写完成,文件加载和加载更加简单,可以支持自定义下载或加载文件的目标目录了\n","*\n","* 23-07-26\n","* 增加可隐藏启动时的不重要信息 通过增加配置 [hidden_console_info = True] 开启\n","*\n","* 23-07-22\n","* 更新了可自动同步收藏目录到 https://huggingface.co/ 的功能\n","* 可通过增加配置项 _huggingface_token = \"token\" 和 _huggingface_repo = “仓库id” 后使用此功能\n","*\n","* 23-07-18 \n","* 如果有两个GPU 第二个GPU将会启动api服务,可用api的方式调用,和webui互相独立,绘图时不会导致另外一边卡顿\n","* 通过/1/作为base url来访问这个api\n","* 没有启动两个webui是因为,很大概率爆内存\n","'''"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["from pathlib import Path\n","import os\n","import time\n","import re\n","import subprocess\n","import threading\n","import sys\n","import socket\n","import torch\n","from typing import List"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["# 内置参数默认值,当上下文有参数时可覆盖默认值\n","\n","_useFrpc = False\n","if 'useFrpc' in locals() or 'useFrpc' in globals():\n"," _useFrpc = useFrpc\n"," \n","_useNgrok = False\n","if 'useNgrok' in locals() or 'useNgrok' in globals():\n"," _useNgrok = useNgrok\n"," \n","_reLoad = False\n","if 'reLoad' in locals() or 'reLoad' in globals():\n"," _reLoad = reLoad\n"," \n","_普通文件列表 = ''\n","if '普通文件列表' in locals() or '普通文件列表' in globals():\n"," _普通文件列表 = 普通文件列表\n","\n","_重要文件列表 = ''\n","if '重要文件列表' in locals() or '重要文件列表' in globals():\n"," _重要文件列表 = 重要文件列表\n","\n","_按顺序加载的重要文件列表 = ''\n","if '按顺序加载的重要文件列表' in locals() or '按顺序加载的重要文件列表' in globals():\n"," _按顺序加载的重要文件列表 = 按顺序加载的重要文件列表\n"," \n","_webuiPort = 7860\n","if 'webuiPort' in locals() or 'webuiPort' in globals():\n"," _webuiPort = webuiPort\n"," \n","_webui_git_repo ='https://github.com/viyiviyi/stable-diffusion-webui.git -b local' \n","if 'webui_git_repo' in locals() or 'webui_git_repo' in globals():\n"," _webui_git_repo = webui_git_repo\\\n"," .replace('{sdui}','stable-diffusion-webui')\\\n"," .replace('{sdwui}',\"webui\")\n"," \n","_webui_config_git_repu = 'https://github.com/viyiviyi/sd-configs.git'\n","if 'webui_config_git_repu' in locals() or 'webui_config_git_repu' in globals():\n"," _webui_config_git_repu = webui_config_git_repu\\\n"," .replace('{sdui}','stable-diffusion-webui')\\\n"," .replace('{sdwui}',\"webui\")\n"," \n"," \n","_huggingface_token = '{input_path}/configs/huggingface_token.txt'\n","if 'huggingface_token' in locals() or 'huggingface_token' in globals():\n"," _huggingface_token = huggingface_token\\\n"," .replace('{sdui}','stable-diffusion-webui')\\\n"," .replace('{sdwui}',\"webui\")\n"," \n","_huggingface_repo = ''\n","if 'huggingface_repo' in locals() or 'huggingface_repo' in globals():\n"," _huggingface_repo = huggingface_repo\\\n"," .replace('{sdui}','stable-diffusion-webui')\\\n"," .replace('{sdwui}',\"webui\")\n","\n","_link_instead_of_copy = True\n","if 'link_instead_of_copy' in locals() or 'link_instead_of_copy' in globals():\n"," _link_instead_of_copy = link_instead_of_copy\n"," \n","show_shell_info = False\n","if 'hidden_console_info' in locals() or 'hidden_console_info' in globals():\n"," show_shell_info = not hidden_console_info\n"," \n","_skip_start = False\n","if 'skip_start' in locals() or 'skip_start' in globals():\n"," _skip_start = skip_start\n"," \n","run_by_none_device = False"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["\n","def run(command, cwd=None, desc=None, errdesc=None, custom_env=None,try_error:bool=True) -> str:\n"," global show_shell_info\n"," if desc is not None:\n"," print(desc)\n","\n"," run_kwargs = {\n"," \"args\": command,\n"," \"shell\": True,\n"," \"cwd\": cwd,\n"," \"env\": os.environ if custom_env is None else custom_env,\n"," \"encoding\": 'utf8',\n"," \"errors\": 'ignore',\n"," }\n","\n"," if not show_shell_info:\n"," run_kwargs[\"stdout\"] = run_kwargs[\"stderr\"] = subprocess.PIPE\n","\n"," result = subprocess.run(**run_kwargs)\n","\n"," if result.returncode != 0:\n"," error_bits = [\n"," f\"{errdesc or 'Error running command'}.\",\n"," f\"Command: {command}\",\n"," f\"Error code: {result.returncode}\",\n"," ]\n"," if result.stdout:\n"," error_bits.append(f\"stdout: {result.stdout}\")\n"," if result.stderr:\n"," error_bits.append(f\"stderr: {result.stderr}\")\n"," if try_error:\n"," print(RuntimeError(\"\\n\".join(error_bits)))\n"," else:\n"," raise RuntimeError(\"\\n\".join(error_bits))\n","\n"," if show_shell_info:\n"," print(result.stdout or \"\")\n"," return (result.stdout or \"\")\n"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["\n","# 检查gpu是否存在\n","def check_gpu():\n"," if not run_by_none_device and torch.cuda.device_count() == 0:\n"," raise Exception('当前环境没有GPU')\n","\n","install_path=f\"{os.environ['HOME']}/sdwui\" # 安装目录\n","output_path=f\"{os.environ['HOME']}/.sdwui/Output\" # 输出目录 如果使用google云盘 会在google云盘增加sdwebui/Output\n","input_path = '/kaggle/input' # 输入目录\n","ui_dir_name = 'sd'\n","google_drive = '' \n","\n","_useGooglrDrive = True\n","if 'useGooglrDrive' in locals() or 'useGooglrDrive' in globals():\n"," _useGooglrDrive = useGooglrDrive\n","\n","# 连接谷歌云\n","try:\n"," if _useGooglrDrive:\n"," from google.colab import drive\n"," drive.mount(f'~/google_drive')\n"," google_drive = f\"{os.environ['HOME']}/google_drive/MyDrive\"\n"," output_path = f'{google_drive}/sdwebui/Output'\n"," input_path = f'{google_drive}/sdwebui/Input'\n"," run(f'''mkdir -p {input_path}''')\n"," print('''\n","已经链接到谷歌云盘\n","云盘根目录/sdwebui/Output 被链接为输出目录,图片和设置文件将会保存在此文件夹\n","云盘根目录/sdwebui/Input 被链接为输入目录,环境变量名是 $input_path, 可以在任何一个配置内通过$input_path或{input_path}来读取文件\n"," ''')\n","except:\n"," _useGooglrDrive = False\n","\n","run(f'''mkdir -p {install_path}''')\n","run(f'''mkdir -p {output_path}''')\n","\n","os.environ['install_path'] = install_path\n","os.environ['output_path'] = output_path\n","os.environ['google_drive'] = google_drive\n","os.environ['input_path'] = input_path\n","\n","def replace_path(input_str:str):\n"," return input_str.replace('$install_path',install_path)\\\n"," .replace('{install_path}',install_path)\\\n"," .replace('$input_path',input_path)\\\n"," .replace('{input_path}',input_path)\\\n"," .replace('$output_path',output_path)\\\n"," .replace('{output_path}',output_path)\\\n"," .replace('{sdui}','stable-diffusion-webui')\\\n"," .replace('{sdwui}',\"webui\")\n","\n","space_string = ' \\n\\r\\t\\'\\\",'\n","\n","def config_reader(conf:str):\n"," args = [replace_path(item.split('#')[0].strip(space_string)) for item in conf.split('\\n') if item.strip(space_string)]\n"," return [item.strip() for item in args if item.strip()]\n"]},{"cell_type":"code","execution_count":null,"metadata":{"_kg_hide-input":true,"id":"i3LhnwYHLCtC","trusted":true},"outputs":[],"source":["ngrokTokenFile = os.path.join(input_path,'configs/ngrok_token.txt') # 非必填 存放ngrokToken的文件的路径\n","frpcConfigFile = os.path.join(input_path,'configs/frpc_koishi.ini') # 非必填 frp 配置文件\n","# ss证书目录 下载nginx的版本,把pem格式改成crt格式\n","frpcSSLFFlies =[os.path.join(input_path,'configs/koishi_ssl')]\n","if 'frpSSL文件' in locals() or 'frpSSL文件' in globals():\n"," frpcSSLFFlies = frpcSSLFFlies + config_reader(frpSSL文件)\n","# frpc 文件目录 如果目录不存在,会自动下载,也可以在数据集搜索 viyiviyi/utils 添加\n","frpcExePath = os.path.join(input_path,'utils-tools/frpc')\n","# 其他需要加载的webui启动参数 写到【参数列表】这个配置去\n","otherArgs = '--xformers'\n","if '参数列表' in locals() or '参数列表' in globals():\n"," otherArgs = ' '.join([item for item in config_reader(参数列表) if item != '--no-gradio-queue'])\n","venvPath = os.path.join(input_path,'sd-webui-venv/venv.tar.bak') # 安装好的python环境 sd-webui-venv是一个公开是数据集 可以搜索添加\n","\n","# 用于使用kaggle api的token文件 参考 https://www.kaggle.com/docs/api\n","# 此文件用于自动上传koishi的相关配置 也可以用于保存重要的输出文件\n","kaggleApiTokenFile = os.path.join(input_path,'configs/kaggle.json')\n","\n","requirements = []\n"]},{"cell_type":"code","execution_count":null,"metadata":{"_kg_hide-input":true,"id":"a_GtG2ayLCtD","trusted":true},"outputs":[],"source":["# 这下面的是用于初始化一些值或者环境变量的,轻易别改\n","_setting_file = '/kaggle/working/configs/config.json'\n","if 'setting_file' in locals() or 'setting_file' in globals():\n"," _setting_file = replace_path(_setting_file)\n","_ui_config_file = '/kaggle/working/configs/ui-config.json'\n","if 'ui_config_file' in locals() or 'ui_config_file' in globals():\n"," _ui_config_file = replace_path(ui_config_file)\n","\n","# 设置文件路径\n","if Path(f\"{os.environ['HOME']}/google_drive/MyDrive\").exists():\n"," if _setting_file == '/kaggle/working/configs/config.json':\n"," _setting_file = os.path.join(output_path,'configs/config.json')\n"," if _ui_config_file == '/kaggle/working/configs/ui-config.json':\n"," _ui_config_file = os.path.join(output_path,'configs/ui-config.json')\n"," \n","frpcStartArg = ''\n","run(f'''mkdir -p {install_path}/configFiles''')\n","if 'frp配置文件或配置' in locals() or 'frp配置文件或配置' in globals():\n"," _frp配置文件或配置 = replace_path(frp配置文件或配置)\n"," if Path(_frp配置文件或配置.strip()).exists():\n"," frpcConfigFile = _frp配置文件或配置.strip()\n"," if not Path(frpcConfigFile).exists(): \n"," if _frp配置文件或配置.strip().startswith('-f'):\n"," frpcStartArg = _frp配置文件或配置.strip()\n"," else:\n"," print('没有frpcp配置')\n"," _useFrpc = False\n"," else:\n"," run(f'''cp -f {frpcConfigFile} {install_path}/configFiles/frpc_webui.ini''')\n"," frpcConfigFile = f'{install_path}/configFiles/frpc_webui.ini'\n"," run(f'''sed -i \"s/local_port = .*/local_port = {_webuiPort}/g\" {frpcConfigFile}''')\n"," frpcStartArg = f' -c {frpcConfigFile}'\n","\n","ngrokToken=''\n","if 'ngrok配置或文件地址' in locals() or 'ngrok配置或文件地址' in globals():\n"," _ngrok配置或文件地址 = replace_path(ngrok配置或文件地址)\n"," if Path(_ngrok配置或文件地址.strip()).exists():\n"," ngrokTokenFile = _ngrok配置或文件地址.strip()\n"," if Path(ngrokTokenFile).exists():\n"," with open(ngrokTokenFile,encoding = \"utf-8\") as nkfile:\n"," ngrokToken = nkfile.readline()\n"," elif not _ngrok配置或文件地址.strip().startswith('/'):\n"," ngrokToken=_ngrok配置或文件地址.strip()\n"," \n","if not Path(venvPath).exists():\n"," venvPath = os.path.join(input_path,'sd-webui-venv/venv.zip')\n"]},{"cell_type":"markdown","metadata":{},"source":["## 文件下载工具\n","\n","---\n","\n","link_or_download_flie(config:str, skip_url:bool=False, _link_instead_of_copy:bool=True, base_path:str = '',sync:bool=False,thread_num:int=None)"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["import concurrent.futures\n","import importlib\n","import os\n","import pprint\n","import re\n","from pathlib import Path\n","from typing import List\n","\n","import requests\n","\n","show_shell_info = False\n","\n","def is_installed(package):\n"," try:\n"," spec = importlib.util.find_spec(package)\n"," except ModuleNotFoundError:\n"," return False\n","\n"," return spec is not None\n","\n","def download_file(url:str, filename:str, dist_path:str, cache_path = '',_link_instead_of_copy:bool=True):\n"," # 获取文件的真实文件名\n"," if not filename:\n"," with requests.get(url, stream=True) as r:\n"," if 'Content-Disposition' in r.headers:\n"," filename = r.headers['Content-Disposition'].split('filename=')[1].strip('\"')\n"," r.close()\n"," if not filename and re.search(r'/[^/]+\\.[^/]+$',url):\n"," filename = url.split('/')[-1]\n"," \n"," filename = re.sub(r'[\\\\/:*?\"<>|;]', '', filename)\n"," filename = re.sub(r'[\\s\\t]+', '_', filename)\n"," \n"," if show_shell_info:\n"," print(f'下载 {filename} url: {url} --> {dist_path}')\n"," \n"," # 创建目录\n"," if cache_path and not Path(cache_path).exists():\n"," os.makedirs(cache_path,exist_ok=True)\n"," if dist_path and not Path(dist_path).exists():\n"," os.makedirs(dist_path,exist_ok=True)\n"," \n"," # 拼接文件的完整路径\n"," filepath = os.path.join(dist_path, filename)\n","\n"," if cache_path:\n"," cache_path = os.path.join(cache_path, filename)\n"," \n"," # 判断文件是否已存在\n"," if Path(filepath).exists():\n"," print(f'文件 {filename} 已存在 {dist_path}')\n"," return\n"," \n"," if cache_path and Path(cache_path).exists():\n"," run(f'cp -n -r -f {\"-s\" if _link_instead_of_copy else \"\"} {cache_path} {dist_path}')\n"," if show_shell_info:\n"," print(f'文件缓存 {cache_path} --> {dist_path}')\n"," return\n"," # 下载文件\n"," with requests.get(url, stream=True) as r:\n"," r.raise_for_status()\n"," with open(cache_path or filepath, 'wb') as f:\n"," for chunk in r.iter_content(chunk_size=8192):\n"," if chunk:\n"," f.write(chunk)\n"," # 如果使用了缓存目录 需要复制或链接文件到目标目录\n"," if cache_path:\n"," run(f'cp -n -r -f {\"-s\" if _link_instead_of_copy else \"\"} {cache_path} {dist_path}')\n"," if show_shell_info:\n"," print(f'下载完成 {filename} --> {dist_path}')\n"," \n","def download_git(url, dist_path, cache_path = '',_link_instead_of_copy:bool=True):\n"," if not Path(dist_path).exists():\n"," os.makedirs(dist_path,exist_ok=True)\n"," if show_shell_info:\n"," print(f'git 下载 {url} --> {dist_path}')\n"," if cache_path and not Path(cache_path).exists():\n"," os.makedirs(cache_path,exist_ok=True)\n"," run(f'git clone {url}',cwd = cache_path)\n"," if cache_path:\n"," run(f'cp -n -r -f {cache_path}/* {dist_path}')\n"," else:\n"," run(f'git clone {url}',cwd = dist_path)\n"," if show_shell_info:\n"," print(f'git 下载完成 {url} --> {dist_path}')\n"," \n"," \n"," \n","# 加入文件到下载列表\n","def pause_url(url:str,dist_path:str):\n"," file_name = ''\n"," if re.match(r'^[^:]+:(https?|ftps?)://', url, flags=0):\n"," file_name = re.findall(r'^[^:]+:',url)[0][:-1]\n"," url = url[len(file_name)+1:]\n"," if not re.match(r'^(https?|ftps?)://',url):\n"," return\n"," file_name = re.sub(r'\\s+','_',file_name or '')\n"," path_hash = str(hash(url)).replace('-','')\n"," \n"," return {'file_name':file_name,'path_hash':path_hash,'url':url,'dist_path':dist_path}\n","\n","def download_urls(download_list:List[dict],sync:bool=False,thread_num:int=5, \n"," cache_path:str=os.path.join(os.environ['HOME'],'.cache','download_util'),\n"," _link_instead_of_copy:bool=True,is_await:bool=False):\n"," if sync:\n"," for conf in download_list:\n"," cache_dir = os.path.join(cache_path,conf['path_hash'])\n"," if conf['url'].startswith('https://github.com'):\n"," download_git(conf['url'],conf['dist_path'],cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy)\n"," continue\n"," download_file(conf['url'],conf['file_name'],conf['dist_path'],cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy)\n"," else:\n"," executor = concurrent.futures.ThreadPoolExecutor(max_workers=thread_num)\n"," futures = []\n"," for conf in download_list:\n"," cache_dir = os.path.join(cache_path,conf['path_hash'])\n"," if conf['url'].startswith('https://github.com'):\n"," futures.append(executor.submit(download_git, conf['url'],conf['dist_path'],\n"," cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy))\n"," continue\n"," futures.append(executor.submit(download_file, conf['url'],conf['file_name'],conf['dist_path'],\n"," cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy))\n"," if is_await:\n"," concurrent.futures.wait(futures)\n"," \n"," \n","def parse_config(config:str):\n"," space_string = ' \\n\\r\\t\\'\\\",'\n"," other_flie_list = [item.split('#')[0].strip(space_string) for item in config.split('\\n') if item.strip(space_string)]\n"," other_flie_list = [item.strip() for item in other_flie_list if item.strip()]\n"," other_flie_list_store = {}\n"," other_flie_list_store_name='default'\n"," other_flie_list_store_list_cache=[]\n"," \n"," for item in other_flie_list:\n"," if item.startswith('[') and item.endswith(']'):\n"," if not other_flie_list_store_name == 'default':\n"," other_flie_list_store[other_flie_list_store_name]=other_flie_list_store_list_cache\n"," other_flie_list_store_list_cache = []\n"," other_flie_list_store_name = item[1:-1]\n"," else:\n"," other_flie_list_store_list_cache.append(item)\n"," other_flie_list_store[other_flie_list_store_name]=other_flie_list_store_list_cache\n"," \n"," return other_flie_list_store\n","\n","\n","def link_or_download_flie(config:str, skip_url:bool=False, _link_instead_of_copy:bool=True, base_path:str = '',\n"," sync:bool=False,thread_num:int=None, is_await:bool=False):\n"," store:dict[str,List[str]] = parse_config(config)\n"," download_list = []\n"," for dist_dir in store.keys():\n"," dist_path = os.path.join(base_path,dist_dir)\n"," os.makedirs(dist_path,exist_ok=True)\n"," for path in store[dist_dir]:\n"," if 'https://' in path or 'http://' in path:\n"," if skip_url:\n"," continue\n"," if sync:\n"," download_urls([pause_url(path,dist_path)],_link_instead_of_copy = _link_instead_of_copy, sync=sync)\n"," continue\n"," download_list.append(pause_url(path,dist_path))\n"," else:\n"," run(f'cp -n -r -f {\"-s\" if _link_instead_of_copy else \"\"} {path} {dist_path}')\n"," if show_shell_info:\n"," print(f'{\"链接\" if _link_instead_of_copy else \"复制\"} {path} --> {dist_path}')\n"," run(f'rm -f {dist_path}/\\*.* ')\n"," if not skip_url:\n"," if show_shell_info:\n"," pprint.pprint(download_list)\n"," download_urls(download_list,_link_instead_of_copy = _link_instead_of_copy, sync=sync, thread_num=thread_num or 2,is_await=is_await)"]},{"cell_type":"markdown","metadata":{"id":"p0uS-BLULCtD"},"source":["## kaggle public API\n","\n","**不能使用%cd这种会改变当前工作目录的命令,会导致和其他线程冲突**\n","\n","---"]},{"cell_type":"code","execution_count":null,"metadata":{"_kg_hide-input":true,"id":"m8FJi4j0LCtD","trusted":true},"outputs":[],"source":["# 安装kaggle的api token文件\n","def initKaggleConfig():\n"," if Path('~/.kaggle/kaggle.json').exists():\n"," return True\n"," if Path(kaggleApiTokenFile).exists():\n"," run(f'''mkdir -p ~/.kaggle/''')\n"," run('cp '+kaggleApiTokenFile+' ~/.kaggle/kaggle.json')\n"," run(f'''chmod 600 ~/.kaggle/kaggle.json''')\n"," return True\n"," print('缺少kaggle的apiToken文件,访问:https://www.kaggle.com/你的kaggle用户名/account 获取')\n"," return False\n","\n","def getUserName():\n"," if not initKaggleConfig(): return\n"," import kaggle\n"," return kaggle.KaggleApi().read_config_file()['username']\n","\n","def createOrUpdateDataSet(path:str,datasetName:str):\n"," if not initKaggleConfig(): return\n"," print('创建或更新数据集 '+datasetName)\n"," import kaggle\n"," run(f'mkdir -p {install_path}/kaggle_cache')\n"," run(f'rm -rf {install_path}/kaggle_cache/*')\n"," datasetDirPath = install_path+'/kaggle_cache/'+datasetName\n"," run('mkdir -p '+datasetDirPath)\n"," run('cp -f '+path+' '+datasetDirPath+'/')\n"," username = getUserName()\n"," print(\"kaggle username:\"+username)\n"," datasetPath = username+'/'+datasetName\n"," datasetList = kaggle.api.dataset_list(mine=True,search=datasetPath)\n"," print(datasetList)\n"," if len(datasetList) == 0 or datasetPath not in [str(d) for d in datasetList]: # 创建 create\n"," run('kaggle datasets init -p' + datasetDirPath)\n"," metadataFile = datasetDirPath+'/dataset-metadata.json'\n"," run('sed -i s/INSERT_TITLE_HERE/'+ datasetName + '/g ' + metadataFile)\n"," run('sed -i s/INSERT_SLUG_HERE/'+ datasetName + '/g ' + metadataFile)\n"," run('cat '+metadataFile)\n"," run('kaggle datasets create -p '+datasetDirPath)\n"," print('create database done')\n"," else:\n"," kaggle.api.dataset_metadata(datasetPath,datasetDirPath)\n"," kaggle.api.dataset_create_version(datasetDirPath, 'auto update',dir_mode='zip')\n"," print('upload database done')\n","\n","def downloadDatasetFiles(datasetName:str,outputPath:str):\n"," if not initKaggleConfig(): return\n"," print('下载数据集文件 '+datasetName)\n"," import kaggle\n"," username = getUserName()\n"," datasetPath = username+'/'+datasetName\n"," datasetList = kaggle.api.dataset_list(mine=True,search=datasetPath)\n"," if datasetPath not in [str(d) for d in datasetList]:\n"," return False\n"," run('mkdir -p '+outputPath)\n"," kaggle.api.dataset_download_files(datasetPath,path=outputPath,unzip=True)\n"," return True\n","\n"]},{"cell_type":"markdown","metadata":{},"source":["## 同步文件夹到 huggingface\n","\n","---"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["# 文件夹与 huggingface 同步\n","if '_huggingface_token' in locals() and '_huggingface_repo' in locals():\n"," if not is_installed('watchdog'):\n"," requirements.append('watchdog')\n"," if not is_installed('huggingface_hub'):\n"," requirements.append('huggingface_hub')\n"," else:\n"," try:\n"," from huggingface_hub import HfApi,login,snapshot_download\n"," except:\n"," requirements.append('huggingface_hub')\n","\n","huggingface_is_init = False\n","\n","def init_huggingface():\n"," if '_huggingface_token' not in globals() or '_huggingface_repo' not in globals():\n"," print('请增加配置项 _huggingface_token = \"token\" 和 _huggingface_repo = “仓库id” 后使用 huggingface 功能')\n"," return False\n"," if not _huggingface_repo or not _huggingface_token:\n"," print('当前无huggingface配置,可配置huggingface仓库和token将收藏的图片保存到huggingface仓库')\n"," return False\n"," global huggingface_is_init\n"," from huggingface_hub import HfApi,login,snapshot_download\n"," token = replace_path(_huggingface_token)\n"," if Path(token).exists():\n"," with open(token,encoding = \"utf-8\") as nkfile:\n"," token = nkfile.readline()\n"," if not token.startswith('hf_'):\n"," print('huggingface token 不正确,请将 token 或 仅存放token 的txt文件路径填入 _huggingface_token 配置')\n"," return False\n"," login(token,add_to_git_credential=True)\n"," huggingface_is_init = True\n"," return True\n","\n","\n","def download__huggingface_repo(repo_id:str,dist_directory:str=None,repo_type='datasets',callback=None):\n"," if not huggingface_is_init:\n"," print('huggingface 相关功能未初始化 请调用 init_huggingface() 初始化')\n"," \n"," if not dist_directory:\n"," dist_directory = f'{install_path}/sd_main_dir/log'\n"," \n"," from huggingface_hub import HfApi,login,snapshot_download\n"," \n"," api = HfApi()\n"," \n"," print('下载收藏的图片')\n"," run(f'''mkdir -p {install_path}/cache/huggingface''')\n"," if not Path(f'{install_path}/cache/huggingface/{repo_id.split(\"/\")[1]}').exists():\n"," run(f'git clone https://huggingface.co/{repo_type}/{repo_id}',cwd=f'{install_path}/cache/huggingface')\n"," run(f'cp -r -f -n -s {install_path}/cache/huggingface/{repo_id.split(\"/\")[1]}/* {dist_directory}')\n","# snapshot_download(repo_id = repo_id, local_dir = dist_directory, local_dir_use_symlinks = \"auto\", token=True, repo_type=repo_type )\n"," if callback:\n"," callback()\n","\n","def start_sync_log_to_huggingface(repo_id:str,directory_to_watch:str=None,repo_type='datasets'):\n"," if not huggingface_is_init:\n"," print('huggingface 相关功能未初始化 请调用 init_huggingface() 初始化')\n"," \n"," from watchdog.observers import Observer\n"," from watchdog.events import FileSystemEventHandler\n"," from huggingface_hub import HfApi,login,snapshot_download\n"," \n"," # 配置监视的目录和 Hugging Face 仓库信息\n"," class FileChangeHandler(FileSystemEventHandler):\n"," def __init__(self, api, repo_id, repo_type):\n"," self.api = api\n"," self.repo_id = repo_id\n"," self.repo_type = repo_type\n"," def on_created(self, event):\n"," if not event.is_directory:\n"," # 上传新文件到 Hugging Face 仓库\n"," file_path = event.src_path\n"," file_name = os.path.basename(file_path)\n"," if file_name[-4:] not in ['.png','.jpg','.txt']: return\n"," try:\n"," self.api.upload_file(\n"," path_or_fileobj=file_path,\n"," path_in_repo=file_path.replace(directory_to_watch,''),\n"," repo_id=self.repo_id,\n"," repo_type=self.repo_type,\n"," )\n"," except Error as error:\n"," print(error)\n","\n"," def on_deleted(self, event):\n"," if not event.is_directory:\n"," # 从 Hugging Face 仓库删除文件\n"," file_path = event.src_path\n"," file_name = os.path.basename(file_path)\n"," if file_name[-4:] not in ['.png','.jpg','.txt']: return\n"," try:\n"," self.api.delete_file(\n"," path_in_repo=file_path.replace(directory_to_watch,''),\n"," repo_id=self.repo_id,\n"," repo_type=self.repo_type,\n"," )\n"," except Error as error:\n"," print(error)\n","\n"," def on_modified(self, event):\n"," if not event.is_directory:\n"," # 更新 Hugging Face 仓库中的文件\n"," file_path = event.src_path\n"," file_name = os.path.basename(file_path)\n"," if file_name[-4:] not in ['.png','.jpg','.txt']: return\n"," try:\n"," self.api.upload_file(\n"," path_or_fileobj=file_path,\n"," path_in_repo=file_path.replace(directory_to_watch,''),\n"," repo_id=self.repo_id,\n"," repo_type=self.repo_type,\n"," )\n"," except Error as error:\n"," print(error)\n","\n"," def on_moved(self, event):\n"," if not event.is_directory:\n"," file_path = event.dest_path\n"," file_name = os.path.basename(file_path)\n"," if file_name[-4:] not in ['.png','.jpg','.txt']: return\n"," if event.dest_path.startswith(directory_to_watch):\n"," try:\n"," self.api.upload_file(\n"," path_or_fileobj=file_path,\n"," path_in_repo=file_path.replace(directory_to_watch,''),\n"," repo_id=self.repo_id,\n"," repo_type=self.repo_type,\n"," )\n"," except Error as error:\n"," print(error)\n","\n"," api = HfApi()\n"," \n"," if not directory_to_watch:\n"," directory_to_watch = f'{install_path}/sd_main_dir/log'\n"," # 创建观察者对象并注册文件变化处理程序\n"," event_handler = FileChangeHandler(api,repo_id,repo_type)\n"," observer = Observer()\n"," observer.schedule(event_handler, directory_to_watch, recursive=True)\n","\n"," # 启动观察者\n"," observer.name = \"solo_directory_to_watch\"\n"," print(f'启动收藏图片文件夹监听,并自动同步到 huggingface {repo_type} : {repo_id}')\n"," observer.start()"]},{"cell_type":"markdown","metadata":{"id":"sswa04veLCtE"},"source":["## 工具函数\n","**不能使用%cd这种会改变当前工作目录的命令,会导致和其他线程冲突**\n","\n","---"]},{"cell_type":"code","execution_count":null,"metadata":{"_kg_hide-input":true,"trusted":true},"outputs":[],"source":["def echoToFile(content:str,path:str):\n"," if path.find('/') >= 0:\n"," _path = '/'.join(path.split('/')[:-1])\n"," run(f'''mkdir -p {_path}''')\n"," with open(path,'w') as sh:\n"," sh.write(content)\n","\n","def zipPath(path:str,zipName:str,format='tar'):\n"," if path.startswith('$install_path'):\n"," path = path.replace('$install_path',install_path)\n"," if path.startswith('$output_path'):\n"," path = path.replace('$install_path',output_path)\n"," if not path.startswith('/'):\n"," path = f'{install_path}/sd_main_dir/{path}'\n"," if Path(path).exists():\n"," if 'tar' == format:\n"," run(f'tar -cf {output_path}/'+ zipName +'.tar -C '+ path +' . ')\n"," elif 'gz' == format:\n"," run(f'tar -czf {output_path}/'+ zipName +'.tar.gz -C '+ path +' . ')\n"," return\n"," print('指定的目录不存在:'+path)\n","\n","# 检查网络\n","def check_service(host, port):\n"," try:\n"," socket.create_connection((host, port), timeout=5)\n"," return True\n"," except socket.error:\n"," return False"]},{"cell_type":"markdown","metadata":{},"source":["## 内网穿透\n","\n","---"]},{"cell_type":"code","execution_count":null,"metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"id":"coqQvTSLLCtE","trusted":true},"outputs":[],"source":["# ngrok\n","def startNgrok(ngrokToken:str,ngrokLocalPort:int):\n"," if not is_installed('pyngrok'):\n"," run(f'pip install pyngrok')\n"," from pyngrok import conf, ngrok\n"," try:\n"," conf.get_default().auth_token = ngrokToken\n"," conf.get_default().monitor_thread = False\n"," ssh_tunnels = ngrok.get_tunnels(conf.get_default())\n"," if len(ssh_tunnels) == 0:\n"," ssh_tunnel = ngrok.connect(ngrokLocalPort)\n"," print('ngrok 访问地址:'+ssh_tunnel.public_url)\n"," else:\n"," print('ngrok 访问地址:'+ssh_tunnels[0].public_url)\n"," except:\n"," print('启动ngrok出错')\n"," \n","def startFrpc(name,configFile):\n"," echoToFile(f'''\n","cd {install_path}/frpc/\n","{install_path}/frpc/frpc {configFile}\n","''',f'{install_path}/frpc/start.sh')\n"," get_ipython().system(f'''bash {install_path}/frpc/start.sh''')\n"," \n","def installProxyExe():\n"," if _useFrpc:\n"," print('安装frpc')\n"," run(f'mkdir -p {install_path}/frpc')\n"," if Path(frpcExePath).exists():\n"," run(f'cp -f -n {frpcExePath} {install_path}/frpc/frpc')\n"," else:\n"," run(f'wget \"https://huggingface.co/datasets/ACCA225/Frp/resolve/main/frpc\" -O {install_path}/frpc/frpc')\n"," \n"," for ssl in frpcSSLFFlies:\n"," if Path(ssl).exists():\n"," run(f'cp -f -n {ssl}/* {install_path}/frpc/')\n"," run(f'chmod +x {install_path}/frpc/frpc')\n"," run(f'{install_path}/frpc/frpc -v')\n"," if _useNgrok and not is_installed('pyngrok'):\n"," run('pip install pyngrok')\n","\n","def startProxy():\n"," if _useNgrok:\n"," startNgrok(ngrokToken,_webuiPort)\n"," if _useFrpc:\n"," startFrpc('frpc_proxy',frpcStartArg)"]},{"cell_type":"markdown","metadata":{},"source":["## NGINX 反向代理\n","\n","---"]},{"cell_type":"code","execution_count":null,"metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"trusted":true},"outputs":[],"source":["\n","# nginx 反向代理配置文件\n","def localProxy():\n"," conf = '''\n","server\n","{\n"," listen '''+str(_webuiPort)+''';\n"," listen [::]:'''+str(_webuiPort)+''';\n"," server_name 127.0.0.1 localhost 0.0.0.0 \"\";\n"," \n"," if ($request_method = OPTIONS) {\n"," return 200;\n"," }\n"," fastcgi_send_timeout 10m;\n"," fastcgi_read_timeout 10m;\n"," fastcgi_connect_timeout 10m;\n"," location /1/\n"," {\n"," proxy_pass http://127.0.0.1:'''+str(_webuiPort+2)+'''/;\n"," # add_header Set-Cookie \"subpath=1; expires=0; Path=/\";\n"," # proxy_set_header Set-Cookie \"subpath=1; expires=0; Path=/\";\n"," proxy_set_header Host $host;\n"," proxy_set_header X-Real-IP $remote_addr;\n"," proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n"," proxy_set_header REMOTE-HOST $remote_addr;\n"," proxy_set_header Upgrade $http_upgrade;\n"," proxy_set_header Connection upgrade;\n"," proxy_http_version 1.1;\n"," proxy_connect_timeout 10m;\n"," proxy_read_timeout 10m;\n"," }\n"," location /\n"," {\n"," set $proxy_url http://127.0.0.1:'''+str(_webuiPort+1)+''';\n"," # if ($cookie_subpath = \"1\") {\n"," # set $proxy_url http://127.0.0.1:'''+str(_webuiPort+2)+''';\n"," # }\n"," proxy_pass $proxy_url;\n"," proxy_set_header Host $host;\n"," proxy_set_header X-Real-IP $remote_addr;\n"," proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n"," proxy_set_header REMOTE-HOST $remote_addr;\n"," proxy_set_header Upgrade $http_upgrade;\n"," proxy_set_header Connection upgrade;\n"," proxy_http_version 1.1;\n"," proxy_connect_timeout 10m;\n"," proxy_read_timeout 10m;\n"," }\n","}\n","'''\n"," echoToFile(conf,'/etc/nginx/conf.d/proxy_nginx.conf')\n"," if not check_service('localhost',_webuiPort):\n"," run(f'''nginx -c /etc/nginx/nginx.conf''')\n"," run(f'''nginx -s reload''')\n"," "]},{"cell_type":"markdown","metadata":{},"source":["## 线程清理工具\n","\n","---\n","\n","清理线程名以 solo_ 开头的所有线程"]},{"cell_type":"code","execution_count":null,"metadata":{"_kg_hide-input":true,"trusted":true},"outputs":[],"source":["import inspect\n","import ctypes\n","\n","def _async_raise(tid, exctype):\n"," \"\"\"raises the exception, performs cleanup if needed\"\"\"\n"," tid = ctypes.c_long(tid)\n"," if not inspect.isclass(exctype):\n"," exctype = type(exctype)\n"," res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))\n"," if res == 0:\n"," raise ValueError(\"invalid thread id\")\n"," elif res != 1:\n"," # \"\"\"if it returns a number greater than one, you're in trouble,\n"," # and you should call it again with exc=NULL to revert the effect\"\"\"\n"," ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)\n"," raise SystemError(\"PyThreadState_SetAsyncExc failed\")\n","\n","def stop_thread(thread):\n"," _async_raise(thread.ident, SystemExit)\n","\n","def stop_solo_threads():\n"," # 获取当前所有活动的线程\n"," threads = threading.enumerate()\n"," # 关闭之前创建的子线程\n"," for thread in threads:\n"," if thread.name.startswith('solo_'):\n"," print(f'结束线程:{thread.name}')\n"," try:\n"," stop_thread(thread)\n"," except socket.error:\n"," print(f'结束线程:{thread.name} 执行失败')"]},{"cell_type":"markdown","metadata":{"id":"Ve3p8oOkLCtE"},"source":["# webui 安装和配置函数\n","---"]},{"cell_type":"code","execution_count":null,"metadata":{"_kg_hide-input":true,"id":"GTjyBJihLCtE","trusted":true},"outputs":[],"source":["envInstalled=False\n","quickStart = True\n","#安装webui\n","def install():\n"," print('安装webui')\n"," os.chdir(f'''{install_path}''')\n"," run(f'''git lfs install''')\n"," run(f'''git config --global credential.helper store''')\n"," for requirement in requirements:\n"," run(f'pip install {requirement}')\n"," if _reLoad:\n"," run(f'''rm -rf sd_main_dir''')\n"," if Path(\"sd_main_dir\").exists():\n"," os.chdir(f'''{install_path}/sd_main_dir/''')\n"," run(f'''git checkout .''')\n"," run(f'''git pull''')\n"," else:\n"," run(f'''git clone {_webui_git_repo} sd_main_dir''')\n"," os.chdir(f'''{install_path}/sd_main_dir''')\n"," print('安装webui 完成')\n","\n","# 链接输出目录\n","def link_dir():\n"," print('链接输出目录')\n"," # 链接图片输出目录\n"," run(f'''mkdir -p {output_path}/outputs''')\n"," run(f'''rm -rf {install_path}/sd_main_dir/outputs''')\n"," run(f'''ln -s -r {output_path}/outputs {install_path}/sd_main_dir/''')\n"," # 输出收藏目录\n"," run(f'''mkdir -p {output_path}/log''')\n"," run(f'''rm -rf {install_path}/sd_main_dir/log''')\n"," run(f'''ln -s -r {output_path}/log {install_path}/sd_main_dir/''')\n"," # 链接训练输出目录 文件夹链接会导致功能不能用\n"," run(f'''rm -rf {install_path}/sd_main_dir/textual_inversion''')\n"," run(f'''mkdir -p {output_path}/textual_inversion/''')\n"," run(f'''ln -s -r {output_path}/textual_inversion {install_path}/sd_main_dir/''')\n"," print('链接输出目录 完成') \n","\n","def install_optimizing():\n"," run('sudo apt install nginx -y')\n"," run('env TF_CPP_MIN_LOG_LEVEL=1')\n"," run('apt -y update -qq')\n"," run('wget http://launchpadlibrarian.net/367274644/libgoogle-perftools-dev_2.5-2.2ubuntu3_amd64.deb')\n"," run('wget https://launchpad.net/ubuntu/+source/google-perftools/2.5-2.2ubuntu3/+build/14795286/+files/google-perftools_2.5-2.2ubuntu3_all.deb')\n"," run('wget https://launchpad.net/ubuntu/+source/google-perftools/2.5-2.2ubuntu3/+build/14795286/+files/libtcmalloc-minimal4_2.5-2.2ubuntu3_amd64.deb')\n"," run('wget https://launchpad.net/ubuntu/+source/google-perftools/2.5-2.2ubuntu3/+build/14795286/+files/libgoogle-perftools4_2.5-2.2ubuntu3_amd64.deb')\n"," run('apt -y install -qq libunwind8-dev')\n"," run('dpkg -i *.deb')\n"," run('env LD_P_reLoad=libtcmalloc.so')\n"," run('rm *.deb')\n"," \n","#安装依赖\n","def install_dependencies():\n"," print('安装webui需要的python环境')\n"," global envInstalled\n"," global venvPath\n"," run(f'''rm -rf {install_path}/sd_main_dir/venv''')\n"," run(f'''mkdir -p {install_path}/sd_main_dir/venv''')\n"," if str(sys.version).startswith('3.10'):\n"," try:\n"," run('python3 -m venv venv' ,cwd=f'{install_path}/sd_main_dir',try_error=False)\n"," except:\n"," run('apt install python3.10-venv -y')\n"," run('python3 -m venv venv' ,cwd=f'{install_path}/sd_main_dir')\n"," else:\n"," run('add-apt-repository ppa:deadsnakes/ppa -y')\n"," run('apt update')\n"," run('apt install python3.10 -y')\n"," run('python3.10 -m venv venv',cwd=f'{install_path}/sd_main_dir')\n"," \n"," if quickStart:\n"," if not Path(venvPath).exists():\n"," run(f'''mkdir -p {install_path}/venv_cache''')\n"," if not Path(f'{install_path}/venv_cache/venv.tar.bak').exists():\n"," download_file('https://huggingface.co/viyi/sdwui/resolve/main/venv.zip','venv.zip',f'{install_path}/venv_cache')\n"," run(f'''unzip {install_path}/venv_cache/venv.zip -d {install_path}/venv_cache''')\n"," venvPath = f'{install_path}/venv_cache/venv.tar.bak'\n"," run(f'''rm -rf {install_path}/venv_cache/venv.zip''')\n"," elif venvPath.endswith('.zip'):\n"," run(f'''mkdir -p {install_path}/venv_cache''')\n"," run(f'''unzip {venvPath} -d {install_path}/venv_cache''')\n"," venvPath = f'{install_path}/venv_cache/venv.tar.bak'\n"," print('解压环境')\n"," run(f'tar -xf {venvPath} -C {install_path}/sd_main_dir/venv')\n"," if not Path(f'{install_path}/sd_main_dir/venv/bin/pip').exists():\n"," run('curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py')\n"," run(f'{install_path}/sd_main_dir/venv/bin/python3 get-pip.py')\n","\n"," get_ipython().system(f'''{install_path}/sd_main_dir/venv/bin/python3 -V''')\n"," get_ipython().system(f'''{install_path}/sd_main_dir/venv/bin/python3 -m pip -V''')\n","\n"," envInstalled = True\n"," print('安装webui需要的python环境 完成')\n"," \n","# 个性化配置 \n","def use_config():\n"," print('使用自定义配置 包括tag翻译 \\n')\n"," run(f'''mkdir -p {install_path}/temp''')\n"," run(f'git clone {_webui_config_git_repu} sd-configs',cwd=f'{install_path}/temp')\n"," run(f'cp -r -f -n {install_path}/temp/sd-configs/dist/* {install_path}/sd_main_dir')\n"," if not Path(_ui_config_file).exists(): # ui配置文件\n"," run(f'''mkdir -p {_ui_config_file[:_ui_config_file.rfind('/')]}''')\n"," run(f'cp -f -n {install_path}/sd_main_dir/ui-config.json {_ui_config_file}')\n"," if not Path(_setting_file).exists(): # 设置配置文件\n"," run(f'''mkdir -p {_setting_file[:_setting_file.rfind('/')]}''')\n"," run(f'cp -f -n {install_path}/sd_main_dir/config.json {_setting_file}')\n","\n","def copy_last_log_to_images():\n"," print('复制编号最大的一张收藏图到输出目录,用于保持编号,否则会出现收藏的图片被覆盖的情况')\n"," img_list = os.listdir(f'{install_path}/sd_main_dir/log/images')\n"," last_img_path = ''\n"," last_img_num = 0\n"," for img in img_list:\n"," if re.findall(r'^\\d+-',str(img)):\n"," num = int(re.findall(r'^\\d+-',str(img))[0][:-1])\n"," if num > last_img_num:\n"," last_img_path = img\n"," last_img_num = num\n"," print(f'{install_path}/sd_main_dir/log/images/{last_img_path} {install_path}/sd_main_dir/outputs/txt2img-images')\n"," run(f'''mkdir -p {install_path}/sd_main_dir/outputs/txt2img-images''')\n"," run(f'''cp -f {install_path}/sd_main_dir/log/images/{last_img_path} {install_path}/sd_main_dir/outputs/txt2img-images/''')\n"," \n"," print(f'{install_path}/sd_main_dir/log/images/{last_img_path} {install_path}/sd_main_dir/outputs/img2img-images')\n"," run(f'''mkdir -p {install_path}/sd_main_dir/outputs/img2img-images''')\n"," run(f'''cp -f {install_path}/sd_main_dir/log/images/{last_img_path} {install_path}/sd_main_dir/outputs/img2img-images/''')\n"," \n","def start_webui(i):\n"," # 只要不爆内存,其他方式关闭后会再次重启 访问地址会发生变化\n"," print(i,'--port',str(_webuiPort+1+i))\n"," if i>0:\n"," print(f'使用第{i+1}张显卡启动第{i+1}个webui,通过frpc或nrgok地址后加/{i}/进行访问(不能使用同一个浏览器)')\n"," if _useFrpc:\n"," restart_times = 0\n"," last_restart_time = time.time()\n"," while True:\n"," get_ipython().system(f'''{install_path}/sd_main_dir/venv/bin/python3 launch.py --device-id={i} --port {str(_webuiPort+1+i)} {'' if i ==0 else '--nowebui'}''')\n"," print('5秒后重启webui')\n"," if time.time() - last_restart_time < 30:\n"," restart_times = restart_times + 1\n"," else:\n"," restart_times = 0\n"," last_restart_time = time.time()\n"," if restart_times >3 :\n"," # 如果90秒内重启了3此,将不再自动重启\n"," break\n"," time.sleep(5)\n"," else:\n"," get_ipython().system(f'''{install_path}/sd_main_dir/venv/bin/python3 launch.py --device-id={i} --port {str(_webuiPort+1+i)} {'' if i ==0 else '--nowebui'}''')\n"," \n","# 启动\n","def start():\n"," print('启动webui')\n"," os.chdir(f'''{install_path}/sd_main_dir''')\n"," args = ''\n"," if _ui_config_file is not None and _ui_config_file != '' and Path(_ui_config_file).exists(): # ui配置文件\n"," args += ' --ui-config-file=' + _ui_config_file\n"," if _setting_file is not None and _setting_file != '' and Path(_setting_file).exists(): # 设置配置文件\n"," args += ' --ui-settings-file=' + _setting_file\n"," args += ' ' + otherArgs\n"," os.environ['COMMANDLINE_ARGS']=args\n"," run(f'''echo COMMANDLINE_ARGS=$COMMANDLINE_ARGS''')\n"," os.environ['REQS_FILE']='requirements.txt'\n","\n"," with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:\n"," for i in range(torch.cuda.device_count() if '多实例' in globals() and 多实例 else 1):\n"," executor.submit(start_webui,i)\n"," while not check_service('localhost',str(_webuiPort+1+i)): # 当当前服务启动完成才允许退出此次循环\n"," time.sleep(5)\n"," time.sleep(10)"]},{"cell_type":"markdown","metadata":{"id":"qLvsk8ByLCtF"},"source":["# 入口函数\n","---"]},{"cell_type":"code","execution_count":null,"metadata":{"_kg_hide-input":true,"id":"IOKjaMlcLCtF","trusted":true},"outputs":[],"source":["\n","# 启动非webui相关的的内容,加快启动速度\n","def main():\n"," global envInstalled\n"," global huggingface_is_init\n"," startTicks = time.time()\n"," stop_solo_threads()\n"," isInstall = True if os.getenv('IsInstall','False') == 'True' else False\n"," if isInstall is False or _reLoad: \n"," print('启动 安装webui和运行环境')\n"," install()\n"," link_dir()\n"," init_huggingface()\n"," threading.Thread(target = install_dependencies,daemon=True,name='solo_install_dependencies').start()\n"," threading.Thread(target = install_optimizing,daemon=True,name='solo_install_optimizing').start()\n"," threading.Thread(target = installProxyExe,daemon=True).start()\n"," link_or_download_flie(replace_path(_普通文件列表), _link_instead_of_copy=_link_instead_of_copy,\n"," base_path=f'{install_path}/sd_main_dir')\n"," if huggingface_is_init:\n"," threading.Thread(target = download__huggingface_repo,daemon=True,\n"," args=([_huggingface_repo]),\n"," kwargs={\"callback\":copy_last_log_to_images},\n"," name='solo_download__huggingface_repo').start()\n"," \n"," link_or_download_flie(replace_path(_重要文件列表), _link_instead_of_copy=_link_instead_of_copy,\n"," base_path=f'{install_path}/sd_main_dir',is_await=True)\n"," t = 0\n"," while not envInstalled:\n"," if t%10==0:\n"," print('等待python环境安装...')\n"," t = t+1\n"," time.sleep(1)\n"," use_config()\n"," localProxy()\n"," os.environ['IsInstall'] = 'True'\n"," else:\n"," envInstalled = True\n"," link_or_download_flie(replace_path(_按顺序加载的重要文件列表), _link_instead_of_copy=_link_instead_of_copy,\n"," base_path=f'{install_path}/sd_main_dir',sync=True)\n"," threading.Thread(target = startProxy, daemon=True, name='solo_startProxy').start()\n"," if init_huggingface():\n"," start_sync_log_to_huggingface(_huggingface_repo)\n"," ticks = time.time()\n"," print(\"加载耗时:\",(ticks - startTicks),\"秒\")\n"," start()\n"]},{"cell_type":"markdown","metadata":{"id":"0oaCRs2gLCtF"},"source":["# 执行区域\n","---"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["print(update_desc)"]},{"cell_type":"code","execution_count":null,"metadata":{"_kg_hide-output":true,"id":"O3DR0DWHLCtF","scrolled":true,"trusted":true},"outputs":[],"source":["# 启动\n","# _reLoad = True\n","# hidden_console_info = False\n","# run_by_none_device = True\n","# show_shell_info = True\n","if _skip_start:\n"," print('已跳过自动启动,可手动执行 main() 进行启动。')\n"," print('''推荐的启动代码:\n","try:\n"," check_gpu() # 检查是否存在gpu\n"," main()\n","except KeyboardInterrupt:\n"," stop_solo_threads() # 中断后自动停止后台线程 (有部分功能在后台线程中运行)\n"," ''')\n","else:\n"," try:\n"," check_gpu()\n"," main()\n"," except KeyboardInterrupt:\n"," stop_solo_threads()"]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.10.12"}},"nbformat":4,"nbformat_minor":4}
|
|
|
|
|
|
sdwui-start-util.dev.ipynb
DELETED
|
@@ -1,1737 +0,0 @@
|
|
| 1 |
-
{
|
| 2 |
-
"cells": [
|
| 3 |
-
{
|
| 4 |
-
"cell_type": "code",
|
| 5 |
-
"execution_count": null,
|
| 6 |
-
"metadata": {
|
| 7 |
-
"trusted": true
|
| 8 |
-
},
|
| 9 |
-
"outputs": [],
|
| 10 |
-
"source": []
|
| 11 |
-
},
|
| 12 |
-
{
|
| 13 |
-
"cell_type": "code",
|
| 14 |
-
"execution_count": null,
|
| 15 |
-
"metadata": {
|
| 16 |
-
"trusted": true
|
| 17 |
-
},
|
| 18 |
-
"outputs": [],
|
| 19 |
-
"source": [
|
| 20 |
-
"update_desc = '''\n",
|
| 21 |
-
"欢迎使用 stable-diffusion-webui 便捷启动工具\n",
|
| 22 |
-
"\n",
|
| 23 |
-
"此脚本理论上可以在任何jupyter环境运行,但仅在 google colab 和 kaggle 测试。 已经无法在 google colab 免费实例上运行。\n",
|
| 24 |
-
"此脚本的【前置脚本】发布地址 https://www.kaggle.com/code/yiyiooo/stable-diffusion-webui-novelai-sdxl。\n",
|
| 25 |
-
"此脚本需配合 【前置脚本】 的脚本附带的配置项才能正常启动。\n",
|
| 26 |
-
"此脚本的内容会自动更新,你无需更新【前置脚本】就能获取到最新的功能。\n",
|
| 27 |
-
"增加一个说明:为解决加密图片的解密和浏览的问题,开发了一个独立应用,可以在这里下载 https://github.com/viyiviyi/encrypt_gallery/releases/\n",
|
| 28 |
-
"加密插件可解决生成nsfw图片后被平台封号问题\n",
|
| 29 |
-
"\n",
|
| 30 |
-
"路径说明\n",
|
| 31 |
-
"* 为了解决平台差异,所有的安装目录和文件输出目录都被重新指定,如果你需要在配置中访问这些目录,请查看以下说明\n",
|
| 32 |
-
"*\n",
|
| 33 |
-
"* 可以使用 $install_path 或 {install_path} 来访问安装目录,写在字符串内也会生效\n",
|
| 34 |
-
"* $output_path 或 {output_path} 可以访问输出目录\n",
|
| 35 |
-
"* 如果你需要安装在自定义目录,也可以设置这些值 如: install_path = '新的路径'\n",
|
| 36 |
-
"* 可自定义方法 on_before_start 并在方法内写上启动前需要的逻辑来实现在webui启动前执行自定义逻辑\n",
|
| 37 |
-
"* 可以增加配置 multi_case = True 来控制是否使用多卡\n",
|
| 38 |
-
"* 如果需要显示更多控制台输出 需配置 hidden_console_info = False\n",
|
| 39 |
-
"\n",
|
| 40 |
-
"********* 特别提示 *********\n",
|
| 41 |
-
"* huggingface 的下载链接需要增加 ?download=true 参数才能正确下载到文件,如果你需要的文件里的下载链接没有这个参数,请自行增加。\n",
|
| 42 |
-
"'''"
|
| 43 |
-
]
|
| 44 |
-
},
|
| 45 |
-
{
|
| 46 |
-
"cell_type": "code",
|
| 47 |
-
"execution_count": null,
|
| 48 |
-
"metadata": {
|
| 49 |
-
"trusted": true
|
| 50 |
-
},
|
| 51 |
-
"outputs": [],
|
| 52 |
-
"source": [
|
| 53 |
-
"from pathlib import Path\n",
|
| 54 |
-
"import os\n",
|
| 55 |
-
"import time\n",
|
| 56 |
-
"import re\n",
|
| 57 |
-
"import subprocess\n",
|
| 58 |
-
"import threading\n",
|
| 59 |
-
"import sys\n",
|
| 60 |
-
"import socket\n",
|
| 61 |
-
"import torch\n",
|
| 62 |
-
"from typing import List\n",
|
| 63 |
-
"import uuid\n",
|
| 64 |
-
"import asyncio\n",
|
| 65 |
-
"from urllib import request"
|
| 66 |
-
]
|
| 67 |
-
},
|
| 68 |
-
{
|
| 69 |
-
"cell_type": "code",
|
| 70 |
-
"execution_count": null,
|
| 71 |
-
"metadata": {
|
| 72 |
-
"trusted": true
|
| 73 |
-
},
|
| 74 |
-
"outputs": [],
|
| 75 |
-
"source": [
|
| 76 |
-
"# 内置参数默认值,当上下文有参数时可覆盖默认值\n",
|
| 77 |
-
"_runing = False\n",
|
| 78 |
-
"\n",
|
| 79 |
-
"_useFrpc = locals().get('useFrpc') or globals().get('useFrpc') or True\n",
|
| 80 |
-
"\n",
|
| 81 |
-
"_useNgrok = locals().get('useNgrok') or globals().get('useNgrok') or True\n",
|
| 82 |
-
"\n",
|
| 83 |
-
"_reLoad = locals().get('reLoad') or globals().get('reLoad') or False\n",
|
| 84 |
-
" \n",
|
| 85 |
-
"_before_downloading = locals().get('before_downloading') or globals().get('before_downloading') or ''\n",
|
| 86 |
-
"\n",
|
| 87 |
-
"_async_downloading = locals().get('async_downloading') or globals().get('async_downloading') or ''\n",
|
| 88 |
-
"\n",
|
| 89 |
-
"_before_start_sync_downloading = locals().get('before_start_sync_downloading') or globals().get('before_start_sync_downloading') or ''\n",
|
| 90 |
-
"\n",
|
| 91 |
-
"_server_port = locals().get('server_port') or globals().get('server_port') or 7860\n",
|
| 92 |
-
" \n",
|
| 93 |
-
"_sd_git_repo = locals().get('sd_git_repo') or globals().get('sd_git_repo') or 'https://github.com/viyiviyi/stable-diffusion-webui.git -b local' \n",
|
| 94 |
-
"_sd_git_repo = _sd_git_repo\\\n",
|
| 95 |
-
" .replace('{sdwui}','stable-diffusion-webui')\\\n",
|
| 96 |
-
" .replace('{wui}',\"webui\")\n",
|
| 97 |
-
" \n",
|
| 98 |
-
"_sd_config_git_repu = locals().get('sd_config_git_repu') or globals().get('sd_config_git_repu') or 'https://github.com/viyiviyi/sd-configs.git'\n",
|
| 99 |
-
"_sd_config_git_repu = _sd_config_git_repu\\\n",
|
| 100 |
-
" .replace('{sdwui}','stable-diffusion-webui')\\\n",
|
| 101 |
-
" .replace('{wui}',\"webui\")\n",
|
| 102 |
-
" \n",
|
| 103 |
-
" \n",
|
| 104 |
-
"_huggingface_token = locals().get('huggingface_token') or globals().get('huggingface_token') or '{input_path}/configs/huggingface_token.txt'\n",
|
| 105 |
-
"_huggingface_token = _huggingface_token\\\n",
|
| 106 |
-
" .replace('{sdwui}','stable-diffusion-webui')\\\n",
|
| 107 |
-
" .replace('{wui}',\"webui\")\n",
|
| 108 |
-
" \n",
|
| 109 |
-
"_huggingface_repo = locals().get('huggingface_repo') or globals().get('huggingface_repo') or ''\n",
|
| 110 |
-
"_huggingface_repo = _huggingface_repo\\\n",
|
| 111 |
-
" .replace('{sdwui}','stable-diffusion-webui')\\\n",
|
| 112 |
-
" .replace('{wui}',\"webui\")\n",
|
| 113 |
-
"\n",
|
| 114 |
-
"_link_instead_of_copy = locals().get('link_instead_of_copy') or globals().get('link_instead_of_copy') or True\n",
|
| 115 |
-
" \n",
|
| 116 |
-
"show_shell_info = locals().get('hidden_console_info') or globals().get('hidden_console_info')\n",
|
| 117 |
-
"if show_shell_info is None: show_shell_info = False\n",
|
| 118 |
-
"else: show_shell_info = not show_shell_info\n",
|
| 119 |
-
"\n",
|
| 120 |
-
"_multi_case = locals().get('multi_case') or globals().get('multi_case') or False\n",
|
| 121 |
-
" \n",
|
| 122 |
-
"_skip_start = locals().get('skip_start') or globals().get('skip_start') or True\n",
|
| 123 |
-
"\n",
|
| 124 |
-
"def before_start():\n",
|
| 125 |
-
" pass\n",
|
| 126 |
-
"\n",
|
| 127 |
-
"def main_start():\n",
|
| 128 |
-
" pass\n",
|
| 129 |
-
"\n",
|
| 130 |
-
"_on_before_start = locals().get('on_before_start') or globals().get('on_before_start') or before_start \n",
|
| 131 |
-
"_skip_webui = locals().get('skip_webui') or globals().get('skip_webui') or False\n",
|
| 132 |
-
" \n",
|
| 133 |
-
"run_by_none_device = False\n",
|
| 134 |
-
"\n",
|
| 135 |
-
"_proxy_path = locals().get('proxy_path') or globals().get('proxy_path') or {}\n",
|
| 136 |
-
"\n",
|
| 137 |
-
"_sub_path = locals().get('sub_path') or globals().get('sub_path') or ['/','/1/']\n",
|
| 138 |
-
"if len(_sub_path) != 2:\n",
|
| 139 |
-
" _sub_path = ['/','/1/']\n",
|
| 140 |
-
" \n",
|
| 141 |
-
"_config_args:dict[str, str] = locals().get('config_args') or globals().get('config_args') or {}"
|
| 142 |
-
]
|
| 143 |
-
},
|
| 144 |
-
{
|
| 145 |
-
"cell_type": "code",
|
| 146 |
-
"execution_count": null,
|
| 147 |
-
"metadata": {
|
| 148 |
-
"trusted": true
|
| 149 |
-
},
|
| 150 |
-
"outputs": [],
|
| 151 |
-
"source": [
|
| 152 |
-
"\n",
|
| 153 |
-
"def run(command, cwd=None, desc=None, errdesc=None, custom_env=None,try_error:bool=True) -> str:\n",
|
| 154 |
-
" global show_shell_info\n",
|
| 155 |
-
" if desc is not None:\n",
|
| 156 |
-
" print(desc)\n",
|
| 157 |
-
"\n",
|
| 158 |
-
" run_kwargs = {\n",
|
| 159 |
-
" \"args\": command,\n",
|
| 160 |
-
" \"shell\": True,\n",
|
| 161 |
-
" \"cwd\": cwd,\n",
|
| 162 |
-
" \"env\": os.environ if custom_env is None else custom_env,\n",
|
| 163 |
-
" \"encoding\": 'utf8',\n",
|
| 164 |
-
" \"errors\": 'ignore',\n",
|
| 165 |
-
" }\n",
|
| 166 |
-
"\n",
|
| 167 |
-
" if not show_shell_info:\n",
|
| 168 |
-
" run_kwargs[\"stdout\"] = run_kwargs[\"stderr\"] = subprocess.PIPE\n",
|
| 169 |
-
"\n",
|
| 170 |
-
" result = subprocess.run(**run_kwargs)\n",
|
| 171 |
-
"\n",
|
| 172 |
-
" if result.returncode != 0:\n",
|
| 173 |
-
" error_bits = [\n",
|
| 174 |
-
" f\"{errdesc or 'Error running command'}.\",\n",
|
| 175 |
-
" f\"Command: {command}\",\n",
|
| 176 |
-
" f\"Error code: {result.returncode}\",\n",
|
| 177 |
-
" ]\n",
|
| 178 |
-
" if result.stdout:\n",
|
| 179 |
-
" error_bits.append(f\"stdout: {result.stdout}\")\n",
|
| 180 |
-
" if result.stderr:\n",
|
| 181 |
-
" error_bits.append(f\"stderr: {result.stderr}\")\n",
|
| 182 |
-
" if try_error:\n",
|
| 183 |
-
" print((RuntimeError(\"\\n\".join(error_bits))))\n",
|
| 184 |
-
" else:\n",
|
| 185 |
-
" raise RuntimeError(\"\\n\".join(error_bits))\n",
|
| 186 |
-
"\n",
|
| 187 |
-
" if show_shell_info:\n",
|
| 188 |
-
" print((result.stdout or \"\"))\n",
|
| 189 |
-
" return (result.stdout or \"\")\n",
|
| 190 |
-
"\n",
|
| 191 |
-
"def mkdirs(path, exist_ok=True):\n",
|
| 192 |
-
" if path and not Path(path).exists():\n",
|
| 193 |
-
" os.makedirs(path,exist_ok=exist_ok)\n",
|
| 194 |
-
"\n",
|
| 195 |
-
"\n",
|
| 196 |
-
"# 检查网络\n",
|
| 197 |
-
"def check_service(host, port):\n",
|
| 198 |
-
" try:\n",
|
| 199 |
-
" socket.create_connection((host, port), timeout=5)\n",
|
| 200 |
-
" return True\n",
|
| 201 |
-
" except socket.error:\n",
|
| 202 |
-
" return False\n",
|
| 203 |
-
"\n",
|
| 204 |
-
"\n",
|
| 205 |
-
"# 检查gpu是否存在\n",
|
| 206 |
-
"def check_gpu():\n",
|
| 207 |
-
" if not run_by_none_device and torch.cuda.device_count() == 0:\n",
|
| 208 |
-
" raise Exception('当前环境没有GPU')\n",
|
| 209 |
-
"\n",
|
| 210 |
-
"\n",
|
| 211 |
-
"def echoToFile(content:str,path:str):\n",
|
| 212 |
-
" if path.find('/') >= 0:\n",
|
| 213 |
-
" _path = '/'.join(path.split('/')[:-1])\n",
|
| 214 |
-
" run(f'''mkdir -p {_path}''')\n",
|
| 215 |
-
" with open(path,'w') as sh:\n",
|
| 216 |
-
" sh.write(content)\n",
|
| 217 |
-
" \n",
|
| 218 |
-
"def get_freefrp_confog(local_port):\n",
|
| 219 |
-
" rd_str = uuid.uuid1()\n",
|
| 220 |
-
" return (f'''\n",
|
| 221 |
-
"[common]\n",
|
| 222 |
-
"server_addr = frp.freefrp.net\n",
|
| 223 |
-
"server_port = 7000\n",
|
| 224 |
-
"token = freefrp.net\n",
|
| 225 |
-
"\n",
|
| 226 |
-
"[{rd_str}_http]\n",
|
| 227 |
-
"type = http\n",
|
| 228 |
-
"local_ip = 127.0.0.1\n",
|
| 229 |
-
"local_port = {local_port}\n",
|
| 230 |
-
"custom_domains = {rd_str}.frp.eaias.com\n",
|
| 231 |
-
"''',f'http://{rd_str}.frp.eaias.com')"
|
| 232 |
-
]
|
| 233 |
-
},
|
| 234 |
-
{
|
| 235 |
-
"cell_type": "code",
|
| 236 |
-
"execution_count": null,
|
| 237 |
-
"metadata": {
|
| 238 |
-
"trusted": true
|
| 239 |
-
},
|
| 240 |
-
"outputs": [],
|
| 241 |
-
"source": [
|
| 242 |
-
"\n",
|
| 243 |
-
"_install_path = f\"/kaggle\" if os.path.exists('/kaggle/') else f\"{os.environ['HOME']}/sd_webui\" # 安装目录\n",
|
| 244 |
-
"_output_path = '/kaggle/working' if os.path.exists('/kaggle/working/') else f\"{os.environ['HOME']}/.sdwui/Output\" # 输出目录 如果使用google云盘 会在google云盘增加sdwebui/Output\n",
|
| 245 |
-
"_input_path = '/kaggle/input' # 输入目录\n",
|
| 246 |
-
"_ui_dir_name = 'sd_main_dir'\n",
|
| 247 |
-
"\n",
|
| 248 |
-
"_install_path = locals().get('install_path') or globals().get('install_path') or _install_path\n",
|
| 249 |
-
"_output_path = locals().get('output_path') or globals().get('output_path') or _output_path\n",
|
| 250 |
-
"_input_path = locals().get('input_path') or globals().get('input_path') or _input_path\n",
|
| 251 |
-
"_ui_dir_name = locals().get('ui_dir_name') or globals().get('ui_dir_name') or _ui_dir_name\n",
|
| 252 |
-
"\n",
|
| 253 |
-
"install_path = _install_path\n",
|
| 254 |
-
"output_path = _output_path\n",
|
| 255 |
-
"input_path = _input_path\n",
|
| 256 |
-
"ui_dir_name = _ui_dir_name\n",
|
| 257 |
-
" \n",
|
| 258 |
-
"google_drive = '' \n",
|
| 259 |
-
"\n",
|
| 260 |
-
"\n",
|
| 261 |
-
"_useGooglrDrive = locals().get('useGooglrDrive') or globals().get('useGooglrDrive') or True\n",
|
| 262 |
-
"\n",
|
| 263 |
-
"# 连接谷歌云\n",
|
| 264 |
-
"try:\n",
|
| 265 |
-
" if _useGooglrDrive:\n",
|
| 266 |
-
" from google.colab import drive\n",
|
| 267 |
-
" drive.mount(f'~/google_drive')\n",
|
| 268 |
-
" google_drive = f\"{os.environ['HOME']}/google_drive/MyDrive\"\n",
|
| 269 |
-
" _output_path = f'{google_drive}/sdwebui/Output'\n",
|
| 270 |
-
" _input_path = f'{google_drive}/sdwebui/Input'\n",
|
| 271 |
-
" run(f'''mkdir -p {_input_path}''')\n",
|
| 272 |
-
" print('''\n",
|
| 273 |
-
"已经链接到谷歌云盘\n",
|
| 274 |
-
"已在云盘创建Input和Output目录\n",
|
| 275 |
-
" ''')\n",
|
| 276 |
-
"except:\n",
|
| 277 |
-
" _useGooglrDrive = False\n",
|
| 278 |
-
"\n",
|
| 279 |
-
"run(f'''mkdir -p {_install_path}''')\n",
|
| 280 |
-
"run(f'''mkdir -p {_output_path}''')\n",
|
| 281 |
-
"\n",
|
| 282 |
-
"\n",
|
| 283 |
-
"os.environ['install_path'] = _install_path\n",
|
| 284 |
-
"os.environ['output_path'] = _output_path\n",
|
| 285 |
-
"os.environ['google_drive'] = google_drive\n",
|
| 286 |
-
"os.environ['input_path'] = _input_path\n",
|
| 287 |
-
"\n",
|
| 288 |
-
"def replace_path(input_str:str):\n",
|
| 289 |
-
" if not input_str: return ''\n",
|
| 290 |
-
" for key in _config_args:\n",
|
| 291 |
-
" input_str = input_str.replace(key,_config_args[key])\n",
|
| 292 |
-
" \n",
|
| 293 |
-
" if not (locals().get('use_comfyui') or globals().get('use_comfyui') or False):\n",
|
| 294 |
-
" input_str = input_str.replace('https://github.com/comfyanonymous/ComfyUI.git','https://github.com/comfyanonymous/ComfyUI.git')\n",
|
| 295 |
-
" \n",
|
| 296 |
-
" return input_str.replace('$install_path',_install_path)\\\n",
|
| 297 |
-
" .replace('{install_path}',_install_path)\\\n",
|
| 298 |
-
" .replace('$input_path',_input_path)\\\n",
|
| 299 |
-
" .replace('{input_path}',_input_path)\\\n",
|
| 300 |
-
" .replace('$output_path',_output_path)\\\n",
|
| 301 |
-
" .replace('{output_path}',_output_path)\\\n",
|
| 302 |
-
" .replace('{sdwui}','stable-diffusion-webui')\\\n",
|
| 303 |
-
" .replace('{wui}',\"webui\")\n",
|
| 304 |
-
"\n",
|
| 305 |
-
"space_string = ' \\n\\r\\t\\'\\\",'\n",
|
| 306 |
-
"\n",
|
| 307 |
-
"def config_reader(conf:str):\n",
|
| 308 |
-
" conf = conf or \"\"\n",
|
| 309 |
-
" args = [replace_path(item.split('#')[0].strip(space_string)) for item in conf.split('\\n') if item.strip(space_string)]\n",
|
| 310 |
-
" return [item.strip() for item in args if item.strip()]\n"
|
| 311 |
-
]
|
| 312 |
-
},
|
| 313 |
-
{
|
| 314 |
-
"cell_type": "code",
|
| 315 |
-
"execution_count": null,
|
| 316 |
-
"metadata": {
|
| 317 |
-
"_kg_hide-input": true,
|
| 318 |
-
"id": "i3LhnwYHLCtC",
|
| 319 |
-
"trusted": true
|
| 320 |
-
},
|
| 321 |
-
"outputs": [],
|
| 322 |
-
"source": [
|
| 323 |
-
"ngrokTokenFile = os.path.join(_input_path,'configs/ngrok_token.txt') # 非必填 存放ngrokToken的文件的路径\n",
|
| 324 |
-
"frpcConfigFile = os.path.join(_input_path,'configs/frpc_koishi.ini') # 非必填 frp 配置文件\n",
|
| 325 |
-
"# ss证书目录 下载nginx的版本,把pem格式改成crt格式\n",
|
| 326 |
-
"frpcSSLFFlies = [os.path.join(_input_path,'configs/koishi_ssl')]\n",
|
| 327 |
-
"if 'frp_ssl_dir' in locals() or 'frp_ssl_dir' in globals():\n",
|
| 328 |
-
" frpcSSLFFlies = frpcSSLFFlies + config_reader(locals().get('frp_ssl_dir') or globals().get('frp_ssl_dir'))\n",
|
| 329 |
-
"# frpc 文件目录 如果目录不存在,会自动下载,也可以在数据集搜索 viyiviyi/utils 添加\n",
|
| 330 |
-
"frpcExePath = os.path.join(_input_path,'utils-tools/frpc')\n",
|
| 331 |
-
"# 其他需要加载的webui启动参数 写到【参数列表】这个配置去\n",
|
| 332 |
-
"otherArgs = '--xformers'\n",
|
| 333 |
-
"if 'sd_start_args' in locals() or 'sd_start_args' in globals():\n",
|
| 334 |
-
" otherArgs = ' '.join([item for item in config_reader(locals().get('sd_start_args') or globals().get('sd_start_args')) if item != '--no-gradio-queue'])\n",
|
| 335 |
-
"venvPath = os.path.join(_input_path,'sd-webui-venv/venv.tar.bak') # 安装好的python环境 sd-webui-venv是一个公开是数据集 可以搜索添加\n",
|
| 336 |
-
"\n",
|
| 337 |
-
"# 用于使用kaggle api的token文件 参考 https://www.kaggle.com/docs/api\n",
|
| 338 |
-
"# 此文件用于自动上传koishi的相关配置 也可以用于保存重要的输出文件\n",
|
| 339 |
-
"kaggleApiTokenFile = os.path.join(_input_path,'configs/kaggle.json')\n",
|
| 340 |
-
"\n",
|
| 341 |
-
"requirements = []\n"
|
| 342 |
-
]
|
| 343 |
-
},
|
| 344 |
-
{
|
| 345 |
-
"cell_type": "code",
|
| 346 |
-
"execution_count": null,
|
| 347 |
-
"metadata": {
|
| 348 |
-
"_kg_hide-input": true,
|
| 349 |
-
"id": "a_GtG2ayLCtD",
|
| 350 |
-
"trusted": true
|
| 351 |
-
},
|
| 352 |
-
"outputs": [],
|
| 353 |
-
"source": [
|
| 354 |
-
"# 这下面的是用于初始化一些值或者环境变量的,轻易别改\n",
|
| 355 |
-
"_setting_file = replace_path(locals().get('setting_file') or globals().get('setting_file') or 'config.json')\n",
|
| 356 |
-
"\n",
|
| 357 |
-
"_ui_config_file = replace_path(locals().get('ui_config_file') or globals().get('ui_config_file') or 'ui-config.json')\n",
|
| 358 |
-
"\n",
|
| 359 |
-
"# 设置文件路径\n",
|
| 360 |
-
"if Path(f\"{os.environ['HOME']}/google_drive/MyDrive\").exists():\n",
|
| 361 |
-
" if _setting_file == '/kaggle/working/configs/config.json':\n",
|
| 362 |
-
" _setting_file = os.path.join(_output_path,'configs/config.json')\n",
|
| 363 |
-
" if _ui_config_file == '/kaggle/working/configs/ui-config.json':\n",
|
| 364 |
-
" _ui_config_file = os.path.join(_output_path,'configs/ui-config.json')\n",
|
| 365 |
-
" \n",
|
| 366 |
-
"frpcStartArg = ''\n",
|
| 367 |
-
"freefrp_url = ''\n",
|
| 368 |
-
"_frp_temp_config_file = ''\n",
|
| 369 |
-
"_frp_config_or_file = replace_path(locals().get('frp_config_or_file') or globals().get('frp_config_or_file')) or frpcConfigFile\n",
|
| 370 |
-
"run(f'''mkdir -p {_install_path}/configFiles''')\n",
|
| 371 |
-
"if _frp_config_or_file:\n",
|
| 372 |
-
" if '[common]' in _frp_config_or_file:\n",
|
| 373 |
-
" echoToFile(_frp_config_or_file,f'{_install_path}/configFiles/temp_frpc_webui.ini')\n",
|
| 374 |
-
" _frp_temp_config_file = f'{_install_path}/configFiles/temp_frpc_webui.ini'\n",
|
| 375 |
-
" elif '.ini' in _frp_config_or_file:\n",
|
| 376 |
-
" _frp_temp_config_file = _frp_config_or_file.strip()\n",
|
| 377 |
-
" \n",
|
| 378 |
-
" if _frp_temp_config_file:\n",
|
| 379 |
-
" if Path(_frp_temp_config_file).exists():\n",
|
| 380 |
-
" run(f'''cp -f {_frp_temp_config_file} {_install_path}/configFiles/frpc_webui.ini''')\n",
|
| 381 |
-
" run(f'''sed -i \"s/local_port = .*/local_port = {_server_port}/g\" {_install_path}/configFiles/frpc_webui.ini''')\n",
|
| 382 |
-
" frpcStartArg = f' -c {_install_path}/configFiles/frpc_webui.ini'\n",
|
| 383 |
-
" elif _frp_config_or_file.strip().startswith('-f'):\n",
|
| 384 |
-
" frpcStartArg = _frp_config_or_file.strip()\n",
|
| 385 |
-
" \n",
|
| 386 |
-
"if not frpcStartArg:\n",
|
| 387 |
-
" conf,url = get_freefrp_confog(_server_port)\n",
|
| 388 |
-
" echoToFile(conf,f'{_install_path}/configFiles/frpc_webui.ini')\n",
|
| 389 |
-
" freefrp_url = url\n",
|
| 390 |
-
" frpcStartArg = f' -c {_install_path}/configFiles/frpc_webui.ini'\n",
|
| 391 |
-
"\n",
|
| 392 |
-
"ngrokToken=''\n",
|
| 393 |
-
"_ngrok_config_or_file = replace_path(locals().get('ngrok_config_or_file') or globals().get('ngrok_config_or_file')) or ngrokTokenFile\n",
|
| 394 |
-
"if _ngrok_config_or_file:\n",
|
| 395 |
-
" if Path(_ngrok_config_or_file.strip()).exists():\n",
|
| 396 |
-
" ngrokTokenFile = _ngrok_config_or_file.strip()\n",
|
| 397 |
-
" if Path(ngrokTokenFile).exists():\n",
|
| 398 |
-
" with open(ngrokTokenFile,encoding = \"utf-8\") as nkfile:\n",
|
| 399 |
-
" ngrokToken = nkfile.readline()\n",
|
| 400 |
-
" elif not _ngrok_config_or_file.strip().startswith('/'):\n",
|
| 401 |
-
" ngrokToken=_ngrok_config_or_file.strip()\n",
|
| 402 |
-
" \n",
|
| 403 |
-
"if not Path(venvPath).exists():\n",
|
| 404 |
-
" venvPath = os.path.join(_input_path,'sd-webui-venv/venv.zip')\n",
|
| 405 |
-
" \n",
|
| 406 |
-
"huggingface_headers:dict = None "
|
| 407 |
-
]
|
| 408 |
-
},
|
| 409 |
-
{
|
| 410 |
-
"cell_type": "code",
|
| 411 |
-
"execution_count": null,
|
| 412 |
-
"metadata": {},
|
| 413 |
-
"outputs": [],
|
| 414 |
-
"source": [
|
| 415 |
-
"def _init_conf():\n",
|
| 416 |
-
" global _useFrpc\n",
|
| 417 |
-
" global _useNgrok\n",
|
| 418 |
-
" global _reLoad\n",
|
| 419 |
-
" global _before_downloading\n",
|
| 420 |
-
" global _async_downloading\n",
|
| 421 |
-
" global _before_start_sync_downloading\n",
|
| 422 |
-
" global _server_port\n",
|
| 423 |
-
" global _sd_git_repo\n",
|
| 424 |
-
" global _sd_config_git_repu\n",
|
| 425 |
-
" global _huggingface_token\n",
|
| 426 |
-
" global _huggingface_repo\n",
|
| 427 |
-
" global _link_instead_of_copy\n",
|
| 428 |
-
" global show_shell_info\n",
|
| 429 |
-
" global _multi_case\n",
|
| 430 |
-
" global _skip_start\n",
|
| 431 |
-
" global _on_before_start\n",
|
| 432 |
-
" global _skip_webui\n",
|
| 433 |
-
" global _proxy_path\n",
|
| 434 |
-
" global _sub_path\n",
|
| 435 |
-
" global _config_args\n",
|
| 436 |
-
" global _install_path\n",
|
| 437 |
-
" global _output_path\n",
|
| 438 |
-
" global _input_path\n",
|
| 439 |
-
" global _ui_dir_name\n",
|
| 440 |
-
" \n",
|
| 441 |
-
" global ngrokTokenFile\n",
|
| 442 |
-
" global frpcConfigFile\n",
|
| 443 |
-
" global frpcSSLFFlies\n",
|
| 444 |
-
" global frpcExePath\n",
|
| 445 |
-
" global otherArgs\n",
|
| 446 |
-
" global _setting_file\n",
|
| 447 |
-
" global _ui_config_file\n",
|
| 448 |
-
" global _frp_temp_config_file\n",
|
| 449 |
-
" global _frp_config_or_file\n",
|
| 450 |
-
" global ngrokToken\n",
|
| 451 |
-
" global venvPath\n",
|
| 452 |
-
" \n",
|
| 453 |
-
" _useFrpc = locals().get('useFrpc') or globals().get('useFrpc') or True\n",
|
| 454 |
-
" _useNgrok = locals().get('useNgrok') or globals().get('useNgrok') or True\n",
|
| 455 |
-
" _reLoad = locals().get('reLoad') or globals().get('reLoad') or False\n",
|
| 456 |
-
" _before_downloading = locals().get('before_downloading') or globals().get('before_downloading') or ''\n",
|
| 457 |
-
" _async_downloading = locals().get('async_downloading') or globals().get('async_downloading') or ''\n",
|
| 458 |
-
" _before_start_sync_downloading = locals().get('before_start_sync_downloading') or globals().get('before_start_sync_downloading') or ''\n",
|
| 459 |
-
" _server_port = locals().get('server_port') or globals().get('server_port') or 7860\n",
|
| 460 |
-
" _sd_git_repo = locals().get('sd_git_repo') or globals().get('sd_git_repo') or 'https://github.com/viyiviyi/stable-diffusion-webui.git -b local' \n",
|
| 461 |
-
" _sd_git_repo = _sd_git_repo\\\n",
|
| 462 |
-
" .replace('{sdwui}','stable-diffusion-webui')\\\n",
|
| 463 |
-
" .replace('{wui}',\"webui\") \n",
|
| 464 |
-
" _sd_config_git_repu = locals().get('sd_config_git_repu') or globals().get('sd_config_git_repu') or 'https://github.com/viyiviyi/sd-configs.git'\n",
|
| 465 |
-
" _sd_config_git_repu = _sd_config_git_repu\\\n",
|
| 466 |
-
" .replace('{sdwui}','stable-diffusion-webui')\\\n",
|
| 467 |
-
" .replace('{wui}',\"webui\")\n",
|
| 468 |
-
" _huggingface_token = locals().get('huggingface_token') or globals().get('huggingface_token') or '{input_path}/configs/huggingface_token.txt'\n",
|
| 469 |
-
" _huggingface_token = _huggingface_token\\\n",
|
| 470 |
-
" .replace('{sdwui}','stable-diffusion-webui')\\\n",
|
| 471 |
-
" .replace('{wui}',\"webui\")\n",
|
| 472 |
-
" _huggingface_repo = locals().get('huggingface_repo') or globals().get('huggingface_repo') or ''\n",
|
| 473 |
-
" _huggingface_repo = _huggingface_repo\\\n",
|
| 474 |
-
" .replace('{sdwui}','stable-diffusion-webui')\\\n",
|
| 475 |
-
" .replace('{wui}',\"webui\")\n",
|
| 476 |
-
" _link_instead_of_copy = locals().get('link_instead_of_copy') or globals().get('link_instead_of_copy') or True\n",
|
| 477 |
-
" show_shell_info = locals().get('hidden_console_info') or globals().get('hidden_console_info')\n",
|
| 478 |
-
" if show_shell_info is None: show_shell_info = False\n",
|
| 479 |
-
" else: show_shell_info = not show_shell_info\n",
|
| 480 |
-
" _multi_case = locals().get('multi_case') or globals().get('multi_case') or False\n",
|
| 481 |
-
" _skip_start = locals().get('skip_start') or globals().get('skip_start') or True\n",
|
| 482 |
-
" _on_before_start = locals().get('on_before_start') or globals().get('on_before_start') or before_start \n",
|
| 483 |
-
" _skip_webui = locals().get('skip_webui') or globals().get('skip_webui') or False\n",
|
| 484 |
-
" _proxy_path = locals().get('proxy_path') or globals().get('proxy_path') or {}\n",
|
| 485 |
-
" _sub_path = locals().get('sub_path') or globals().get('sub_path') or ['/','/1/']\n",
|
| 486 |
-
" if len(_sub_path) != 2:\n",
|
| 487 |
-
" _sub_path = ['/','/1/']\n",
|
| 488 |
-
" \n",
|
| 489 |
-
" _config_args = locals().get('config_args') or globals().get('config_args') or {}\n",
|
| 490 |
-
" \n",
|
| 491 |
-
" _install_path = locals().get('install_path') or globals().get('install_path') or _install_path\n",
|
| 492 |
-
" _output_path = locals().get('output_path') or globals().get('output_path') or _output_path\n",
|
| 493 |
-
" _input_path = locals().get('input_path') or globals().get('input_path') or _input_path\n",
|
| 494 |
-
" _ui_dir_name = locals().get('ui_dir_name') or globals().get('ui_dir_name') or _ui_dir_name\n",
|
| 495 |
-
" \n",
|
| 496 |
-
" ngrokTokenFile = os.path.join(_input_path,'configs/ngrok_token.txt') # 非必填 存放ngrokToken的文件的路径\n",
|
| 497 |
-
" frpcConfigFile = os.path.join(_input_path,'configs/frpc_koishi.ini') # 非必填 frp 配置文件\n",
|
| 498 |
-
" # ss证书目录 下载nginx的版本,把pem格式改成crt格式\n",
|
| 499 |
-
" frpcSSLFFlies = [os.path.join(_input_path,'configs/koishi_ssl')]\n",
|
| 500 |
-
" if 'frp_ssl_dir' in locals() or 'frp_ssl_dir' in globals():\n",
|
| 501 |
-
" frpcSSLFFlies = frpcSSLFFlies + config_reader(locals().get('frp_ssl_dir') or globals().get('frp_ssl_dir'))\n",
|
| 502 |
-
" # frpc 文件目录 如果目录不存在,会自动下载,也可以在数据集搜索 viyiviyi/utils 添加\n",
|
| 503 |
-
" frpcExePath = os.path.join(_input_path,'utils-tools/frpc')\n",
|
| 504 |
-
" # 其他需要加载的webui启动参数 写到【参数列表】这个配置去\n",
|
| 505 |
-
" otherArgs = '--xformers'\n",
|
| 506 |
-
" if 'sd_start_args' in locals() or 'sd_start_args' in globals():\n",
|
| 507 |
-
" otherArgs = ' '.join([item for item in config_reader(locals().get('sd_start_args') or globals().get('sd_start_args')) if item != '--no-gradio-queue'])\n",
|
| 508 |
-
"\n",
|
| 509 |
-
" # 这下面的是用于初始化一些值或者环境变量的,轻易别改\n",
|
| 510 |
-
" _setting_file = replace_path(locals().get('setting_file') or globals().get('setting_file') or 'config.json')\n",
|
| 511 |
-
"\n",
|
| 512 |
-
" _ui_config_file = replace_path(locals().get('ui_config_file') or globals().get('ui_config_file') or 'ui-config.json')\n",
|
| 513 |
-
"\n",
|
| 514 |
-
" # 设置文件路径\n",
|
| 515 |
-
" if Path(f\"{os.environ['HOME']}/google_drive/MyDrive\").exists():\n",
|
| 516 |
-
" if _setting_file == '/kaggle/working/configs/config.json':\n",
|
| 517 |
-
" _setting_file = os.path.join(_output_path,'configs/config.json')\n",
|
| 518 |
-
" if _ui_config_file == '/kaggle/working/configs/ui-config.json':\n",
|
| 519 |
-
" _ui_config_file = os.path.join(_output_path,'configs/ui-config.json')\n",
|
| 520 |
-
" \n",
|
| 521 |
-
" frpcStartArg = ''\n",
|
| 522 |
-
" freefrp_url = ''\n",
|
| 523 |
-
" _frp_temp_config_file = ''\n",
|
| 524 |
-
" _frp_config_or_file = replace_path(locals().get('frp_config_or_file') or globals().get('frp_config_or_file')) or frpcConfigFile\n",
|
| 525 |
-
" run(f'''mkdir -p {_install_path}/configFiles''')\n",
|
| 526 |
-
" if _frp_config_or_file:\n",
|
| 527 |
-
" if '[common]' in _frp_config_or_file:\n",
|
| 528 |
-
" echoToFile(_frp_config_or_file,f'{_install_path}/configFiles/temp_frpc_webui.ini')\n",
|
| 529 |
-
" _frp_temp_config_file = f'{_install_path}/configFiles/temp_frpc_webui.ini'\n",
|
| 530 |
-
" elif '.ini' in _frp_config_or_file:\n",
|
| 531 |
-
" _frp_temp_config_file = _frp_config_or_file.strip()\n",
|
| 532 |
-
" \n",
|
| 533 |
-
" if _frp_temp_config_file:\n",
|
| 534 |
-
" if Path(_frp_temp_config_file).exists():\n",
|
| 535 |
-
" run(f'''cp -f {_frp_temp_config_file} {_install_path}/configFiles/frpc_webui.ini''')\n",
|
| 536 |
-
" run(f'''sed -i \"s/local_port = .*/local_port = {_server_port}/g\" {_install_path}/configFiles/frpc_webui.ini''')\n",
|
| 537 |
-
" frpcStartArg = f' -c {_install_path}/configFiles/frpc_webui.ini'\n",
|
| 538 |
-
" elif _frp_config_or_file.strip().startswith('-f'):\n",
|
| 539 |
-
" frpcStartArg = _frp_config_or_file.strip()\n",
|
| 540 |
-
" \n",
|
| 541 |
-
" if not frpcStartArg:\n",
|
| 542 |
-
" conf,url = get_freefrp_confog(_server_port)\n",
|
| 543 |
-
" echoToFile(conf,f'{_install_path}/configFiles/frpc_webui.ini')\n",
|
| 544 |
-
" freefrp_url = url\n",
|
| 545 |
-
" frpcStartArg = f' -c {_install_path}/configFiles/frpc_webui.ini'\n",
|
| 546 |
-
"\n",
|
| 547 |
-
" ngrokToken=''\n",
|
| 548 |
-
" _ngrok_config_or_file = replace_path(locals().get('ngrok_config_or_file') or globals().get('ngrok_config_or_file')) or ngrokTokenFile\n",
|
| 549 |
-
" if _ngrok_config_or_file:\n",
|
| 550 |
-
" if Path(_ngrok_config_or_file.strip()).exists():\n",
|
| 551 |
-
" ngrokTokenFile = _ngrok_config_or_file.strip()\n",
|
| 552 |
-
" if Path(ngrokTokenFile).exists():\n",
|
| 553 |
-
" with open(ngrokTokenFile,encoding = \"utf-8\") as nkfile:\n",
|
| 554 |
-
" ngrokToken = nkfile.readline()\n",
|
| 555 |
-
" elif not _ngrok_config_or_file.strip().startswith('/'):\n",
|
| 556 |
-
" ngrokToken=_ngrok_config_or_file.strip()\n",
|
| 557 |
-
" \n",
|
| 558 |
-
" if not Path(venvPath).exists():\n",
|
| 559 |
-
" venvPath = os.path.join(_input_path,'sd-webui-venv/venv.zip')\n",
|
| 560 |
-
" "
|
| 561 |
-
]
|
| 562 |
-
},
|
| 563 |
-
{
|
| 564 |
-
"cell_type": "markdown",
|
| 565 |
-
"metadata": {},
|
| 566 |
-
"source": [
|
| 567 |
-
"## 文件下载工具\n",
|
| 568 |
-
"\n",
|
| 569 |
-
"---\n",
|
| 570 |
-
"\n",
|
| 571 |
-
"link_or_download_flie(config:str, skip_url:bool=False, _link_instead_of_copy:bool=True, base_path:str = '',sync:bool=False,thread_num:int=None)"
|
| 572 |
-
]
|
| 573 |
-
},
|
| 574 |
-
{
|
| 575 |
-
"cell_type": "code",
|
| 576 |
-
"execution_count": null,
|
| 577 |
-
"metadata": {
|
| 578 |
-
"trusted": true
|
| 579 |
-
},
|
| 580 |
-
"outputs": [],
|
| 581 |
-
"source": [
|
| 582 |
-
"import concurrent.futures\n",
|
| 583 |
-
"import importlib\n",
|
| 584 |
-
"import os\n",
|
| 585 |
-
"import pprint\n",
|
| 586 |
-
"import re\n",
|
| 587 |
-
"import venv\n",
|
| 588 |
-
"from pathlib import Path\n",
|
| 589 |
-
"from typing import List\n",
|
| 590 |
-
"\n",
|
| 591 |
-
"import requests\n",
|
| 592 |
-
"\n",
|
| 593 |
-
"show_shell_info = False\n",
|
| 594 |
-
"\n",
|
| 595 |
-
"def is_installed(package):\n",
|
| 596 |
-
" try:\n",
|
| 597 |
-
" spec = importlib.util.find_spec(package)\n",
|
| 598 |
-
" except ModuleNotFoundError:\n",
|
| 599 |
-
" return False\n",
|
| 600 |
-
"\n",
|
| 601 |
-
" return spec is not None\n",
|
| 602 |
-
"\n",
|
| 603 |
-
"def download_file(url:str, filename:str, dist_path:str, cache_path = '',_link_instead_of_copy:bool=True,headers={}):\n",
|
| 604 |
-
" startTicks = time.time()\n",
|
| 605 |
-
" # 获取文件的真实文件名\n",
|
| 606 |
-
" if not filename:\n",
|
| 607 |
-
" with requests.get(url, stream=True,headers=headers) as r:\n",
|
| 608 |
-
" if 'Content-Disposition' in r.headers:\n",
|
| 609 |
-
" filename = r.headers['Content-Disposition'].split('filename=')[1].strip('\"')\n",
|
| 610 |
-
" r.close()\n",
|
| 611 |
-
" if not filename and re.search(r'/[^/]+\\.[^/]+$',url):\n",
|
| 612 |
-
" filename = url.split('/')[-1].split('?')[0]\n",
|
| 613 |
-
" \n",
|
| 614 |
-
" filename = re.sub(r'[\\\\/:*?\"<>|;]', '', filename)\n",
|
| 615 |
-
" filename = re.sub(r'[\\s\\t]+', '_', filename)\n",
|
| 616 |
-
" \n",
|
| 617 |
-
" print(f'下载 {filename} url: {url} --> {dist_path}')\n",
|
| 618 |
-
" \n",
|
| 619 |
-
" # 创建目录\n",
|
| 620 |
-
" if cache_path and not Path(cache_path).exists():\n",
|
| 621 |
-
" os.makedirs(cache_path,exist_ok=True)\n",
|
| 622 |
-
" if dist_path and not Path(dist_path).exists():\n",
|
| 623 |
-
" os.makedirs(dist_path,exist_ok=True)\n",
|
| 624 |
-
" \n",
|
| 625 |
-
" # 拼接文件的完整路径\n",
|
| 626 |
-
" filepath = os.path.join(dist_path, filename)\n",
|
| 627 |
-
"\n",
|
| 628 |
-
" if cache_path:\n",
|
| 629 |
-
" cache_path = os.path.join(cache_path, filename)\n",
|
| 630 |
-
" \n",
|
| 631 |
-
" # 判断文件是否已存在\n",
|
| 632 |
-
" if Path(filepath).exists():\n",
|
| 633 |
-
" print(f'文件 {filename} 已存在 {dist_path}')\n",
|
| 634 |
-
" return\n",
|
| 635 |
-
" \n",
|
| 636 |
-
" if cache_path and Path(cache_path).exists():\n",
|
| 637 |
-
" run(f'cp -n -r -f {\"-s\" if _link_instead_of_copy else \"\"} {cache_path} {dist_path}')\n",
|
| 638 |
-
" print(f'文件缓存 {cache_path} --> {dist_path}')\n",
|
| 639 |
-
" return\n",
|
| 640 |
-
" # 下载文件\n",
|
| 641 |
-
" size = 0\n",
|
| 642 |
-
" with requests.get(url, stream=True, headers=headers) as r:\n",
|
| 643 |
-
" r.raise_for_status()\n",
|
| 644 |
-
" with open(cache_path or filepath, 'wb') as f:\n",
|
| 645 |
-
" for chunk in r.iter_content(chunk_size=1024*1024):\n",
|
| 646 |
-
" if chunk:\n",
|
| 647 |
-
" size += len(chunk)\n",
|
| 648 |
-
" f.write(chunk)\n",
|
| 649 |
-
" # 如果使用了缓存目录 需要复制或链接文件到目标目录\n",
|
| 650 |
-
" if cache_path:\n",
|
| 651 |
-
" run(f'cp -n -r -f {\"-s\" if _link_instead_of_copy else \"\"} {cache_path} {dist_path}')\n",
|
| 652 |
-
" ticks = time.time()\n",
|
| 653 |
-
" print(f'下载完成 {filename} --> {dist_path} 大小{round(size/1024/1024,2)}M 耗时:{round(ticks - startTicks,2)}秒')\n",
|
| 654 |
-
" \n",
|
| 655 |
-
"def download_git(url, dist_path, cache_path = '',_link_instead_of_copy:bool=True):\n",
|
| 656 |
-
" if not Path(dist_path).exists():\n",
|
| 657 |
-
" os.makedirs(dist_path,exist_ok=True)\n",
|
| 658 |
-
" if show_shell_info:\n",
|
| 659 |
-
" print(f'git 下载 {url} --> {dist_path}')\n",
|
| 660 |
-
" if cache_path and not Path(cache_path).exists():\n",
|
| 661 |
-
" os.makedirs(cache_path,exist_ok=True)\n",
|
| 662 |
-
" run(f'git clone {url}',cwd = cache_path)\n",
|
| 663 |
-
" if cache_path:\n",
|
| 664 |
-
" run(f'cp -n -r -f {cache_path}/* {dist_path}')\n",
|
| 665 |
-
" else:\n",
|
| 666 |
-
" run(f'git clone {url}',cwd = dist_path)\n",
|
| 667 |
-
" if show_shell_info:\n",
|
| 668 |
-
" print(f'git 下载完成 {url} --> {dist_path}')\n",
|
| 669 |
-
" \n",
|
| 670 |
-
" \n",
|
| 671 |
-
"def download_huggingface(url:str, filename:str, dist_path, cache_path = '',_link_instead_of_copy:bool=True):\n",
|
| 672 |
-
" fileReg = r'^https:\\/\\/huggingface.co(\\/([^\\/]+\\/)?[^\\/]+\\/[^\\/]+\\/(resolve|blob)\\/[^\\/]+\\/|[^\\.]+\\.[^\\.]+$|download=true)'\n",
|
| 673 |
-
" def isFile(url:str):\n",
|
| 674 |
-
" if re.match(fileReg,url):\n",
|
| 675 |
-
" return True\n",
|
| 676 |
-
" return False\n",
|
| 677 |
-
" if isFile(url):\n",
|
| 678 |
-
" download_file(url,filename,dist_path,cache_path,_link_instead_of_copy,headers=huggingface_headers)\n",
|
| 679 |
-
" else:\n",
|
| 680 |
-
" download_git(url,dist_path,cache_path,_link_instead_of_copy)\n",
|
| 681 |
-
" \n",
|
| 682 |
-
"# 加入文件到下载列表\n",
|
| 683 |
-
"def pause_url(url:str,dist_path:str):\n",
|
| 684 |
-
" file_name = ''\n",
|
| 685 |
-
" if re.match(r'^[^:]+:(https?|ftps?)://', url, flags=0):\n",
|
| 686 |
-
" file_name = re.findall(r'^[^:]+:',url)[0][:-1]\n",
|
| 687 |
-
" url = url[len(file_name)+1:]\n",
|
| 688 |
-
" if not re.match(r'^(https?|ftps?)://',url):\n",
|
| 689 |
-
" return\n",
|
| 690 |
-
" file_name = re.sub(r'\\s+','_',file_name or '')\n",
|
| 691 |
-
" path_hash = str(hash(url)).replace('-','')\n",
|
| 692 |
-
" \n",
|
| 693 |
-
" return {'file_name':file_name,'path_hash':path_hash,'url':url,'dist_path':dist_path}\n",
|
| 694 |
-
"\n",
|
| 695 |
-
"def download_urls(download_list:List[dict],sync:bool=False,thread_num:int=5, \n",
|
| 696 |
-
" cache_path:str=os.path.join(os.environ['HOME'],'.cache','download_util'),\n",
|
| 697 |
-
" _link_instead_of_copy:bool=True,is_await:bool=False):\n",
|
| 698 |
-
" if sync:\n",
|
| 699 |
-
" for conf in download_list:\n",
|
| 700 |
-
" cache_dir = os.path.join(cache_path,conf['path_hash'])\n",
|
| 701 |
-
" if conf['url'].startswith('https://github.com'):\n",
|
| 702 |
-
" try:\n",
|
| 703 |
-
" download_git(conf['url'],conf['dist_path'],cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy)\n",
|
| 704 |
-
" except:\n",
|
| 705 |
-
" pass\n",
|
| 706 |
-
" continue\n",
|
| 707 |
-
" if conf['url'].startswith('https://huggingface.co'):\n",
|
| 708 |
-
" try:\n",
|
| 709 |
-
" download_huggingface(conf['url'],conf['file_name'],conf['dist_path'],cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy)\n",
|
| 710 |
-
" except:\n",
|
| 711 |
-
" pass\n",
|
| 712 |
-
" continue\n",
|
| 713 |
-
" if conf['url'].startswith('https://civitai.com'):\n",
|
| 714 |
-
" if not re.search(r'token=.+', conf['url']):\n",
|
| 715 |
-
" if conf['url'].find('?') == -1:\n",
|
| 716 |
-
" conf['url'] = conf['url']+'?token=fee8bb78b75566eddfd04d061996185c'\n",
|
| 717 |
-
" else:\n",
|
| 718 |
-
" conf['url'] = conf['url']+'&token=fee8bb78b75566eddfd04d061996185c'\n",
|
| 719 |
-
" try:\n",
|
| 720 |
-
" download_file(conf['url'],conf['file_name'],conf['dist_path'],cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy)\n",
|
| 721 |
-
" except:\n",
|
| 722 |
-
" pass\n",
|
| 723 |
-
" else:\n",
|
| 724 |
-
" executor = concurrent.futures.ThreadPoolExecutor(max_workers=thread_num)\n",
|
| 725 |
-
" futures = []\n",
|
| 726 |
-
" for conf in download_list:\n",
|
| 727 |
-
" cache_dir = os.path.join(cache_path,conf['path_hash'])\n",
|
| 728 |
-
" if conf['url'].startswith('https://github.com'):\n",
|
| 729 |
-
" futures.append(executor.submit(download_git, conf['url'],conf['dist_path'],\n",
|
| 730 |
-
" cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy))\n",
|
| 731 |
-
" continue\n",
|
| 732 |
-
" if conf['url'].startswith('https://huggingface.co'):\n",
|
| 733 |
-
" futures.append(executor.submit(download_huggingface,conf['url'],conf['file_name'],conf['dist_path'],cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy))\n",
|
| 734 |
-
" continue\n",
|
| 735 |
-
" if conf['url'].startswith('https://civitai.com'):\n",
|
| 736 |
-
" if not re.search(r'token=.+', conf['url']):\n",
|
| 737 |
-
" if conf['url'].find('?') == -1:\n",
|
| 738 |
-
" conf['url'] = conf['url']+'?token=fee8bb78b75566eddfd04d061996185c'\n",
|
| 739 |
-
" else:\n",
|
| 740 |
-
" conf['url'] = conf['url']+'&token=fee8bb78b75566eddfd04d061996185c'\n",
|
| 741 |
-
" futures.append(executor.submit(download_file, conf['url'],conf['file_name'],conf['dist_path'],\n",
|
| 742 |
-
" cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy))\n",
|
| 743 |
-
" if is_await:\n",
|
| 744 |
-
" concurrent.futures.wait(futures)\n",
|
| 745 |
-
" \n",
|
| 746 |
-
" \n",
|
| 747 |
-
"def parse_config(config:str):\n",
|
| 748 |
-
" space_string = ' \\n\\r\\t\\'\\\",'\n",
|
| 749 |
-
" other_flie_list = [item.split('#')[0].strip(space_string) for item in config.split('\\n') if item.strip(space_string)]\n",
|
| 750 |
-
" other_flie_list = [item.strip() for item in other_flie_list if item.strip()]\n",
|
| 751 |
-
" other_flie_list_store = {}\n",
|
| 752 |
-
" other_flie_list_store_name='default'\n",
|
| 753 |
-
" other_flie_list_store_list_cache=[]\n",
|
| 754 |
-
" \n",
|
| 755 |
-
" for item in other_flie_list:\n",
|
| 756 |
-
" if item.startswith('[') and item.endswith(']'):\n",
|
| 757 |
-
" if not other_flie_list_store_name == 'default':\n",
|
| 758 |
-
" other_flie_list_store[other_flie_list_store_name]=other_flie_list_store_list_cache\n",
|
| 759 |
-
" other_flie_list_store_list_cache = []\n",
|
| 760 |
-
" other_flie_list_store_name = item[1:-1]\n",
|
| 761 |
-
" else:\n",
|
| 762 |
-
" other_flie_list_store_list_cache.append(item)\n",
|
| 763 |
-
" other_flie_list_store[other_flie_list_store_name]=other_flie_list_store_list_cache\n",
|
| 764 |
-
" \n",
|
| 765 |
-
" return other_flie_list_store\n",
|
| 766 |
-
"\n",
|
| 767 |
-
"\n",
|
| 768 |
-
"def link_or_download_flie(config:str, skip_url:bool=False, _link_instead_of_copy:bool=True, base_path:str = '',\n",
|
| 769 |
-
" sync:bool=False,thread_num:int=None, is_await:bool=False):\n",
|
| 770 |
-
" store:dict[str,List[str]] = parse_config(config)\n",
|
| 771 |
-
" download_list = []\n",
|
| 772 |
-
" for dist_dir in store.keys():\n",
|
| 773 |
-
" dist_path = os.path.join(base_path,dist_dir)\n",
|
| 774 |
-
" os.makedirs(dist_path,exist_ok=True)\n",
|
| 775 |
-
" for path in store[dist_dir]:\n",
|
| 776 |
-
" if 'https://' in path or 'http://' in path:\n",
|
| 777 |
-
" if skip_url:\n",
|
| 778 |
-
" continue\n",
|
| 779 |
-
" if sync:\n",
|
| 780 |
-
" try:\n",
|
| 781 |
-
" download_urls([pause_url(path,dist_path)],_link_instead_of_copy = _link_instead_of_copy, sync=sync)\n",
|
| 782 |
-
" except:\n",
|
| 783 |
-
" pass\n",
|
| 784 |
-
" continue\n",
|
| 785 |
-
" download_list.append(pause_url(path,dist_path))\n",
|
| 786 |
-
" else:\n",
|
| 787 |
-
" run(f'cp -n -r -f {\"-s\" if _link_instead_of_copy else \"\"} {path} {dist_path}')\n",
|
| 788 |
-
" if show_shell_info:\n",
|
| 789 |
-
" print(f'{\"链接\" if _link_instead_of_copy else \"复制\"} {path} --> {dist_path}')\n",
|
| 790 |
-
" run(f'rm -f {dist_path}/\\*.* ')\n",
|
| 791 |
-
" if not skip_url:\n",
|
| 792 |
-
" if show_shell_info:\n",
|
| 793 |
-
" pprint.pprint(download_list)\n",
|
| 794 |
-
" try:\n",
|
| 795 |
-
" download_urls(download_list,_link_instead_of_copy = _link_instead_of_copy, sync=sync, thread_num=thread_num or 3,is_await=is_await)\n",
|
| 796 |
-
" except:\n",
|
| 797 |
-
" pass"
|
| 798 |
-
]
|
| 799 |
-
},
|
| 800 |
-
{
|
| 801 |
-
"cell_type": "markdown",
|
| 802 |
-
"metadata": {
|
| 803 |
-
"id": "p0uS-BLULCtD"
|
| 804 |
-
},
|
| 805 |
-
"source": [
|
| 806 |
-
"## kaggle public API\n",
|
| 807 |
-
"\n",
|
| 808 |
-
"**不能使用%cd这种会改变当前工作目录的命令,会导致和其他线程冲突**\n",
|
| 809 |
-
"\n",
|
| 810 |
-
"---"
|
| 811 |
-
]
|
| 812 |
-
},
|
| 813 |
-
{
|
| 814 |
-
"cell_type": "code",
|
| 815 |
-
"execution_count": null,
|
| 816 |
-
"metadata": {
|
| 817 |
-
"_kg_hide-input": true,
|
| 818 |
-
"id": "m8FJi4j0LCtD",
|
| 819 |
-
"trusted": true
|
| 820 |
-
},
|
| 821 |
-
"outputs": [],
|
| 822 |
-
"source": [
|
| 823 |
-
"# 安装kaggle的api token文件\n",
|
| 824 |
-
"def initKaggleConfig():\n",
|
| 825 |
-
" if Path('~/.kaggle/kaggle.json').exists():\n",
|
| 826 |
-
" return True\n",
|
| 827 |
-
" if Path(kaggleApiTokenFile).exists():\n",
|
| 828 |
-
" run(f'''mkdir -p ~/.kaggle/''')\n",
|
| 829 |
-
" run('cp '+kaggleApiTokenFile+' ~/.kaggle/kaggle.json')\n",
|
| 830 |
-
" run(f'''chmod 600 ~/.kaggle/kaggle.json''')\n",
|
| 831 |
-
" return True\n",
|
| 832 |
-
" print('缺少kaggle的apiToken文件,访问:https://www.kaggle.com/你的kaggle用户名/account 获取')\n",
|
| 833 |
-
" return False\n",
|
| 834 |
-
"\n",
|
| 835 |
-
"def getUserName():\n",
|
| 836 |
-
" if not initKaggleConfig(): return\n",
|
| 837 |
-
" import kaggle\n",
|
| 838 |
-
" return kaggle.KaggleApi().read_config_file()['username']\n",
|
| 839 |
-
"\n",
|
| 840 |
-
"def createOrUpdateDataSet(path:str,datasetName:str):\n",
|
| 841 |
-
" if not initKaggleConfig(): return\n",
|
| 842 |
-
" print('创建或更新数据集 '+datasetName)\n",
|
| 843 |
-
" import kaggle\n",
|
| 844 |
-
" run(f'mkdir -p {_install_path}/kaggle_cache')\n",
|
| 845 |
-
" run(f'rm -rf {_install_path}/kaggle_cache/*')\n",
|
| 846 |
-
" datasetDirPath = _install_path+'/kaggle_cache/'+datasetName\n",
|
| 847 |
-
" run('mkdir -p '+datasetDirPath)\n",
|
| 848 |
-
" run('cp -f '+path+' '+datasetDirPath+'/')\n",
|
| 849 |
-
" username = getUserName()\n",
|
| 850 |
-
" print(\"kaggle username:\"+username)\n",
|
| 851 |
-
" datasetPath = username+'/'+datasetName\n",
|
| 852 |
-
" datasetList = kaggle.api.dataset_list(mine=True,search=datasetPath)\n",
|
| 853 |
-
" print(datasetList)\n",
|
| 854 |
-
" if len(datasetList) == 0 or datasetPath not in [str(d) for d in datasetList]: # 创建 create\n",
|
| 855 |
-
" run('kaggle datasets init -p' + datasetDirPath)\n",
|
| 856 |
-
" metadataFile = datasetDirPath+'/dataset-metadata.json'\n",
|
| 857 |
-
" run('sed -i s/INSERT_TITLE_HERE/'+ datasetName + '/g ' + metadataFile)\n",
|
| 858 |
-
" run('sed -i s/INSERT_SLUG_HERE/'+ datasetName + '/g ' + metadataFile)\n",
|
| 859 |
-
" run('cat '+metadataFile)\n",
|
| 860 |
-
" run('kaggle datasets create -p '+datasetDirPath)\n",
|
| 861 |
-
" print('create database done')\n",
|
| 862 |
-
" else:\n",
|
| 863 |
-
" kaggle.api.dataset_metadata(datasetPath,datasetDirPath)\n",
|
| 864 |
-
" kaggle.api.dataset_create_version(datasetDirPath, 'auto update',dir_mode='zip')\n",
|
| 865 |
-
" print('upload database done')\n",
|
| 866 |
-
"\n",
|
| 867 |
-
"def downloadDatasetFiles(datasetName:str,outputPath:str):\n",
|
| 868 |
-
" if not initKaggleConfig(): return\n",
|
| 869 |
-
" print('下载数据集文件 '+datasetName)\n",
|
| 870 |
-
" import kaggle\n",
|
| 871 |
-
" username = getUserName()\n",
|
| 872 |
-
" datasetPath = username+'/'+datasetName\n",
|
| 873 |
-
" datasetList = kaggle.api.dataset_list(mine=True,search=datasetPath)\n",
|
| 874 |
-
" if datasetPath not in [str(d) for d in datasetList]:\n",
|
| 875 |
-
" return False\n",
|
| 876 |
-
" run('mkdir -p '+outputPath)\n",
|
| 877 |
-
" kaggle.api.dataset_download_files(datasetPath,path=outputPath,unzip=True)\n",
|
| 878 |
-
" return True\n",
|
| 879 |
-
"\n"
|
| 880 |
-
]
|
| 881 |
-
},
|
| 882 |
-
{
|
| 883 |
-
"cell_type": "markdown",
|
| 884 |
-
"metadata": {},
|
| 885 |
-
"source": [
|
| 886 |
-
"## 同步文件夹到 huggingface\n",
|
| 887 |
-
"\n",
|
| 888 |
-
"---"
|
| 889 |
-
]
|
| 890 |
-
},
|
| 891 |
-
{
|
| 892 |
-
"cell_type": "code",
|
| 893 |
-
"execution_count": null,
|
| 894 |
-
"metadata": {
|
| 895 |
-
"trusted": true
|
| 896 |
-
},
|
| 897 |
-
"outputs": [],
|
| 898 |
-
"source": [
|
| 899 |
-
"# 文件夹与 huggingface 同步\n",
|
| 900 |
-
"if _huggingface_token and _huggingface_repo:\n",
|
| 901 |
-
" if not is_installed('watchdog'):\n",
|
| 902 |
-
" requirements.append('watchdog')\n",
|
| 903 |
-
" if not is_installed('huggingface_hub'):\n",
|
| 904 |
-
" requirements.append('huggingface_hub')\n",
|
| 905 |
-
" else:\n",
|
| 906 |
-
" try:\n",
|
| 907 |
-
" from huggingface_hub import HfApi,login,snapshot_download\n",
|
| 908 |
-
" except:\n",
|
| 909 |
-
" requirements.append('huggingface_hub')\n",
|
| 910 |
-
"\n",
|
| 911 |
-
"huggingface_is_init = False\n",
|
| 912 |
-
"\n",
|
| 913 |
-
"def init_huggingface():\n",
|
| 914 |
-
" if not _huggingface_token:\n",
|
| 915 |
-
" return False\n",
|
| 916 |
-
"\n",
|
| 917 |
-
" global huggingface_headers\n",
|
| 918 |
-
" global huggingface_is_init\n",
|
| 919 |
-
" \n",
|
| 920 |
-
" from huggingface_hub import login\n",
|
| 921 |
-
" token = replace_path(_huggingface_token)\n",
|
| 922 |
-
" if not _huggingface_token.startswith('hf_') and Path(token).exists():\n",
|
| 923 |
-
" with open(token,encoding = \"utf-8\") as nkfile:\n",
|
| 924 |
-
" token = nkfile.readline()\n",
|
| 925 |
-
" if not token.startswith('hf_'):\n",
|
| 926 |
-
" print('huggingface token 不正确,请将 token 或 仅存放token 的txt文件路径填入 _huggingface_token 配置')\n",
|
| 927 |
-
" return False\n",
|
| 928 |
-
" login(token,add_to_git_credential=True)\n",
|
| 929 |
-
" huggingface_headers = {'Authorization': 'Bearer '+token}\n",
|
| 930 |
-
" print('huggingface token 已经加载,可以下载私有仓库或文件')\n",
|
| 931 |
-
" \n",
|
| 932 |
-
" if not _huggingface_repo:\n",
|
| 933 |
-
" print('huggingface 同步收藏图片功能不会启动,可增加配置项 huggingface_token = \"token\" 和 huggingface_repo = “仓库id” 后启用 huggingface 同步收藏图片功能')\n",
|
| 934 |
-
" return False\n",
|
| 935 |
-
" huggingface_is_init = True\n",
|
| 936 |
-
" return True\n",
|
| 937 |
-
"\n",
|
| 938 |
-
"\n",
|
| 939 |
-
"def download__huggingface_repo(repo_id:str,dist_directory:str=None,repo_type='dataset',callback=None):\n",
|
| 940 |
-
" if not huggingface_is_init:\n",
|
| 941 |
-
" print('huggingface 相关功能未初始化 请调用 init_huggingface() 初始化')\n",
|
| 942 |
-
" \n",
|
| 943 |
-
" if not dist_directory:\n",
|
| 944 |
-
" dist_directory = f'{_install_path}/{_ui_dir_name}/log'\n",
|
| 945 |
-
" \n",
|
| 946 |
-
" print('下载收藏的图片')\n",
|
| 947 |
-
" if not Path(f'{_install_path}/cache/huggingface/huggingface_repo').exists():\n",
|
| 948 |
-
" mkdirs(f'{_install_path}/cache/huggingface')\n",
|
| 949 |
-
" repo_path = ''\n",
|
| 950 |
-
" if repo_type == 'dataset':\n",
|
| 951 |
-
" repo_path = 'datasets'\n",
|
| 952 |
-
" if repo_type == 'space':\n",
|
| 953 |
-
" repo_path = 'spaces'\n",
|
| 954 |
-
" if repo_path:\n",
|
| 955 |
-
" run(f'git clone https://huggingface.co/{repo_path}/{repo_id} huggingface_repo',cwd=f'{_install_path}/cache/huggingface')\n",
|
| 956 |
-
" else:\n",
|
| 957 |
-
" run(f'git clone https://huggingface.co/{repo_id} huggingface_repo',cwd=f'{_install_path}/cache/huggingface')\n",
|
| 958 |
-
" if Path(f'{_install_path}/cache/huggingface/huggingface_repo').exists():\n",
|
| 959 |
-
" run(f'cp -r -f -n -s {_install_path}/cache/huggingface/huggingface_repo/* {dist_directory}')\n",
|
| 960 |
-
" if callback:\n",
|
| 961 |
-
" callback()\n",
|
| 962 |
-
"\n",
|
| 963 |
-
"def start_sync_log_to_huggingface(repo_id:str,directory_to_watch:str=None,repo_type='dataset'):\n",
|
| 964 |
-
" if not huggingface_is_init:\n",
|
| 965 |
-
" print('huggingface 相关功能未初始化 请调用 init_huggingface() 初始化')\n",
|
| 966 |
-
" \n",
|
| 967 |
-
" from watchdog.observers import Observer\n",
|
| 968 |
-
" from watchdog.events import FileSystemEventHandler\n",
|
| 969 |
-
" from huggingface_hub import HfApi,login,snapshot_download\n",
|
| 970 |
-
" \n",
|
| 971 |
-
" # 配置监视的目录和 Hugging Face 仓库信息\n",
|
| 972 |
-
" class FileChangeHandler(FileSystemEventHandler):\n",
|
| 973 |
-
" def __init__(self, api, repo_id, repo_type,directory_to_watch):\n",
|
| 974 |
-
" self.api = api\n",
|
| 975 |
-
" self.repo_id = repo_id\n",
|
| 976 |
-
" self.repo_type = repo_type\n",
|
| 977 |
-
" self.directory_to_watch = directory_to_watch\n",
|
| 978 |
-
" def on_created(self, event):\n",
|
| 979 |
-
" if not event.is_directory:\n",
|
| 980 |
-
" # 上传新文件到 Hugging Face 仓库\n",
|
| 981 |
-
" file_path = event.src_path\n",
|
| 982 |
-
" file_name:str = os.path.basename(file_path)\n",
|
| 983 |
-
" print(file_name)\n",
|
| 984 |
-
" if file_name[file_name.rindex('.'):] not in ['.png','.jpg','.txt','.webp','.jpeg']: return\n",
|
| 985 |
-
" print(file_name,'>>','huggingface')\n",
|
| 986 |
-
" try:\n",
|
| 987 |
-
" self.api.upload_file(\n",
|
| 988 |
-
" path_or_fileobj=file_path,\n",
|
| 989 |
-
" path_in_repo=file_path.replace(self.directory_to_watch,''),\n",
|
| 990 |
-
" repo_id=self.repo_id,\n",
|
| 991 |
-
" repo_type=self.repo_type,\n",
|
| 992 |
-
" )\n",
|
| 993 |
-
" except IOError as error:\n",
|
| 994 |
-
" print(error)\n",
|
| 995 |
-
"\n",
|
| 996 |
-
" def on_deleted(self, event):\n",
|
| 997 |
-
" if not event.is_directory:\n",
|
| 998 |
-
" # 从 Hugging Face 仓库删除文件\n",
|
| 999 |
-
" file_path = event.src_path\n",
|
| 1000 |
-
" file_name = os.path.basename(file_path)\n",
|
| 1001 |
-
" if file_name[file_name.rindex('.'):] not in ['.png','.jpg','.txt','.webp','.jpeg']: return\n",
|
| 1002 |
-
" try:\n",
|
| 1003 |
-
" self.api.delete_file(\n",
|
| 1004 |
-
" path_in_repo=file_path.replace(self.directory_to_watch,''),\n",
|
| 1005 |
-
" repo_id=self.repo_id,\n",
|
| 1006 |
-
" repo_type=self.repo_type,\n",
|
| 1007 |
-
" )\n",
|
| 1008 |
-
" except IOError as error:\n",
|
| 1009 |
-
" print(error)\n",
|
| 1010 |
-
"\n",
|
| 1011 |
-
" def on_modified(self, event):\n",
|
| 1012 |
-
" if not event.is_directory:\n",
|
| 1013 |
-
" # 更新 Hugging Face 仓库中的文件\n",
|
| 1014 |
-
" file_path = event.src_path\n",
|
| 1015 |
-
" file_name = os.path.basename(file_path)\n",
|
| 1016 |
-
" if file_name[file_name.rindex('.'):] not in ['.png','.jpg','.txt','.webp','.jpeg']: return\n",
|
| 1017 |
-
" try:\n",
|
| 1018 |
-
" self.api.upload_file(\n",
|
| 1019 |
-
" path_or_fileobj=file_path,\n",
|
| 1020 |
-
" path_in_repo=file_path.replace(self.directory_to_watch,''),\n",
|
| 1021 |
-
" repo_id=self.repo_id,\n",
|
| 1022 |
-
" repo_type=self.repo_type,\n",
|
| 1023 |
-
" )\n",
|
| 1024 |
-
" except IOError as error:\n",
|
| 1025 |
-
" print(error)\n",
|
| 1026 |
-
"\n",
|
| 1027 |
-
" def on_moved(self, event):\n",
|
| 1028 |
-
" if not event.is_directory:\n",
|
| 1029 |
-
" file_path = event.dest_path\n",
|
| 1030 |
-
" file_name = os.path.basename(file_path)\n",
|
| 1031 |
-
" if file_name[file_name.rindex('.'):] not in ['.png','.jpg','.txt','.webp','.jpeg']: return\n",
|
| 1032 |
-
" if event.dest_path.startswith(self.directory_to_watch):\n",
|
| 1033 |
-
" try:\n",
|
| 1034 |
-
" self.api.upload_file(\n",
|
| 1035 |
-
" path_or_fileobj=file_path,\n",
|
| 1036 |
-
" path_in_repo=file_path.replace(self.directory_to_watch,''),\n",
|
| 1037 |
-
" repo_id=self.repo_id,\n",
|
| 1038 |
-
" repo_type=self.repo_type,\n",
|
| 1039 |
-
" )\n",
|
| 1040 |
-
" except IOError as error:\n",
|
| 1041 |
-
" print(error)\n",
|
| 1042 |
-
"\n",
|
| 1043 |
-
" api = HfApi()\n",
|
| 1044 |
-
" \n",
|
| 1045 |
-
" if not directory_to_watch:\n",
|
| 1046 |
-
" directory_to_watch = f'{_install_path}/{_ui_dir_name}/log'\n",
|
| 1047 |
-
" # 创建观察者对象并注册文件变化处理程序\n",
|
| 1048 |
-
" event_handler = FileChangeHandler(api,repo_id,repo_type,directory_to_watch)\n",
|
| 1049 |
-
" observer = Observer()\n",
|
| 1050 |
-
" observer.schedule(event_handler, directory_to_watch, recursive=True)\n",
|
| 1051 |
-
"\n",
|
| 1052 |
-
" # 启动观察者\n",
|
| 1053 |
-
" observer.name = \"solo_directory_to_watch\"\n",
|
| 1054 |
-
" print(f'启动收藏图片文件夹监听,并自动同步到 huggingface {repo_type} : {repo_id}')\n",
|
| 1055 |
-
" observer.start()"
|
| 1056 |
-
]
|
| 1057 |
-
},
|
| 1058 |
-
{
|
| 1059 |
-
"cell_type": "markdown",
|
| 1060 |
-
"metadata": {
|
| 1061 |
-
"id": "sswa04veLCtE"
|
| 1062 |
-
},
|
| 1063 |
-
"source": [
|
| 1064 |
-
"## 工具函数\n",
|
| 1065 |
-
"**不能使用%cd这种会改变当前工作目录的命令,会导致和其他线程冲突**\n",
|
| 1066 |
-
"\n",
|
| 1067 |
-
"---"
|
| 1068 |
-
]
|
| 1069 |
-
},
|
| 1070 |
-
{
|
| 1071 |
-
"cell_type": "code",
|
| 1072 |
-
"execution_count": null,
|
| 1073 |
-
"metadata": {
|
| 1074 |
-
"_kg_hide-input": true,
|
| 1075 |
-
"trusted": true
|
| 1076 |
-
},
|
| 1077 |
-
"outputs": [],
|
| 1078 |
-
"source": [
|
| 1079 |
-
"\n",
|
| 1080 |
-
"def zipPath(path:str,zipName:str,format='tar'):\n",
|
| 1081 |
-
" if path.startswith('$install_path'):\n",
|
| 1082 |
-
" path = path.replace('$install_path',_install_path)\n",
|
| 1083 |
-
" if path.startswith('$output_path'):\n",
|
| 1084 |
-
" path = path.replace('$install_path',_output_path)\n",
|
| 1085 |
-
" if not path.startswith('/'):\n",
|
| 1086 |
-
" path = f'{_install_path}/{_ui_dir_name}/{path}'\n",
|
| 1087 |
-
" if Path(path).exists():\n",
|
| 1088 |
-
" if 'tar' == format:\n",
|
| 1089 |
-
" run(f'tar -cf {_output_path}/'+ zipName +'.tar -C '+ path +' . ')\n",
|
| 1090 |
-
" elif 'gz' == format:\n",
|
| 1091 |
-
" run(f'tar -czf {_output_path}/'+ zipName +'.tar.gz -C '+ path +' . ')\n",
|
| 1092 |
-
" return\n",
|
| 1093 |
-
" print('指定的目录不存在:'+path)\n",
|
| 1094 |
-
" \n",
|
| 1095 |
-
"def get_folder_list(directory:str): \n",
|
| 1096 |
-
" folder_list = [] \n",
|
| 1097 |
-
" for item in os.listdir(directory): \n",
|
| 1098 |
-
" if os.path.isdir(os.path.join(directory, item)): \n",
|
| 1099 |
-
" folder_list.append(item) \n",
|
| 1100 |
-
" return folder_list\n",
|
| 1101 |
-
"\n",
|
| 1102 |
-
"def read_text_file(file_path:str):\n",
|
| 1103 |
-
" if not Path(file_path).exists(): return ''\n",
|
| 1104 |
-
" with open(file_path,\"r\") as f:\n",
|
| 1105 |
-
" text = file.read()\n",
|
| 1106 |
-
" if text: return text.strip()\n",
|
| 1107 |
-
" return ''"
|
| 1108 |
-
]
|
| 1109 |
-
},
|
| 1110 |
-
{
|
| 1111 |
-
"cell_type": "markdown",
|
| 1112 |
-
"metadata": {},
|
| 1113 |
-
"source": [
|
| 1114 |
-
"## 内网穿透\n",
|
| 1115 |
-
"\n",
|
| 1116 |
-
"---"
|
| 1117 |
-
]
|
| 1118 |
-
},
|
| 1119 |
-
{
|
| 1120 |
-
"cell_type": "code",
|
| 1121 |
-
"execution_count": null,
|
| 1122 |
-
"metadata": {
|
| 1123 |
-
"_kg_hide-input": true,
|
| 1124 |
-
"_kg_hide-output": true,
|
| 1125 |
-
"id": "coqQvTSLLCtE",
|
| 1126 |
-
"trusted": true
|
| 1127 |
-
},
|
| 1128 |
-
"outputs": [],
|
| 1129 |
-
"source": [
|
| 1130 |
-
"def printUrl(url,name=''):\n",
|
| 1131 |
-
" print(f'{name} 访问地址:{url}')\n",
|
| 1132 |
-
" for key in sorted(_proxy_path.keys(), key=len)[::-1]:\n",
|
| 1133 |
-
" print(f'{name} 本地服务:{_proxy_path[key]} 访问地址:{url}{key}')\n",
|
| 1134 |
-
"# ngrok\n",
|
| 1135 |
-
"def startNgrok(ngrokToken:str,ngrokLocalPort:int):\n",
|
| 1136 |
-
" if not is_installed('pyngrok'):\n",
|
| 1137 |
-
" run('pip install pyngrok')\n",
|
| 1138 |
-
" from pyngrok import conf, ngrok\n",
|
| 1139 |
-
" try:\n",
|
| 1140 |
-
" conf.get_default().auth_token = ngrokToken\n",
|
| 1141 |
-
" conf.get_default().monitor_thread = False\n",
|
| 1142 |
-
" ssh_tunnels = ngrok.get_tunnels(conf.get_default())\n",
|
| 1143 |
-
" url = ''\n",
|
| 1144 |
-
" if len(ssh_tunnels) == 0:\n",
|
| 1145 |
-
" ssh_tunnel = ngrok.connect(ngrokLocalPort)\n",
|
| 1146 |
-
" url = ssh_tunnel.public_url\n",
|
| 1147 |
-
" print('ngrok 访问地址:'+ssh_tunnel.public_url)\n",
|
| 1148 |
-
" else:\n",
|
| 1149 |
-
" print('ngrok 访问地址:'+ssh_tunnels[0].public_url)\n",
|
| 1150 |
-
" url = ssh_tunnels[0].public_url\n",
|
| 1151 |
-
" printUrl(url,'ngrok')\n",
|
| 1152 |
-
" def auto_request_ngrok():\n",
|
| 1153 |
-
" if url:\n",
|
| 1154 |
-
" while(_runing):\n",
|
| 1155 |
-
" time.sleep(60*1)\n",
|
| 1156 |
-
" try:\n",
|
| 1157 |
-
" res = requests.get(url+'/',headers={\"ngrok-skip-browser-warning\" : \"1\"},timeout=10)\n",
|
| 1158 |
-
" except:\n",
|
| 1159 |
-
" ''\n",
|
| 1160 |
-
" # print('自动调用ngrok链接以保存链接不会断开',res.status_code)\n",
|
| 1161 |
-
"\n",
|
| 1162 |
-
" # threading.Thread(target = auto_request_ngrok,daemon=True,name='solo_auto_request_ngrok').start()\n",
|
| 1163 |
-
" except:\n",
|
| 1164 |
-
" print('启动ngrok出错')\n",
|
| 1165 |
-
" \n",
|
| 1166 |
-
"def startFrpc(name,configFile):\n",
|
| 1167 |
-
" if not Path(f'{_install_path}/frpc/frpc').exists():\n",
|
| 1168 |
-
" installFrpExe()\n",
|
| 1169 |
-
" if freefrp_url:\n",
|
| 1170 |
-
" printUrl(freefrp_url,'freefrp')\n",
|
| 1171 |
-
" echoToFile(f'''\n",
|
| 1172 |
-
"cd {_install_path}/frpc/\n",
|
| 1173 |
-
"{_install_path}/frpc/frpc {configFile}\n",
|
| 1174 |
-
"''',f'{_install_path}/frpc/start.sh')\n",
|
| 1175 |
-
" get_ipython().system(f'''bash {_install_path}/frpc/start.sh''')\n",
|
| 1176 |
-
" \n",
|
| 1177 |
-
"def installFrpExe():\n",
|
| 1178 |
-
" if _useFrpc:\n",
|
| 1179 |
-
" print('安装frpc')\n",
|
| 1180 |
-
" run(f'mkdir -p {_install_path}/frpc')\n",
|
| 1181 |
-
" if Path(frpcExePath).exists():\n",
|
| 1182 |
-
" run(f'cp -f -n {frpcExePath} {_install_path}/frpc/frpc')\n",
|
| 1183 |
-
" else:\n",
|
| 1184 |
-
" run(f'wget \"https://huggingface.co/datasets/ACCA225/Frp/resolve/main/frpc\" -O {_install_path}/frpc/frpc')\n",
|
| 1185 |
-
" \n",
|
| 1186 |
-
" for ssl in frpcSSLFFlies:\n",
|
| 1187 |
-
" if Path(ssl).exists():\n",
|
| 1188 |
-
" run(f'cp -f -n {ssl}/* {_install_path}/frpc/')\n",
|
| 1189 |
-
" run(f'chmod +x {_install_path}/frpc/frpc')\n",
|
| 1190 |
-
" run(f'{_install_path}/frpc/frpc -v')\n",
|
| 1191 |
-
"\n",
|
| 1192 |
-
"def startProxy():\n",
|
| 1193 |
-
" if _useNgrok:\n",
|
| 1194 |
-
" startNgrok(ngrokToken,_server_port)\n",
|
| 1195 |
-
" if _useFrpc:\n",
|
| 1196 |
-
" startFrpc('frpc_proxy',frpcStartArg)"
|
| 1197 |
-
]
|
| 1198 |
-
},
|
| 1199 |
-
{
|
| 1200 |
-
"cell_type": "markdown",
|
| 1201 |
-
"metadata": {},
|
| 1202 |
-
"source": [
|
| 1203 |
-
"## NGINX 反向代理\n",
|
| 1204 |
-
"\n",
|
| 1205 |
-
"---"
|
| 1206 |
-
]
|
| 1207 |
-
},
|
| 1208 |
-
{
|
| 1209 |
-
"cell_type": "code",
|
| 1210 |
-
"execution_count": null,
|
| 1211 |
-
"metadata": {
|
| 1212 |
-
"_kg_hide-input": true,
|
| 1213 |
-
"_kg_hide-output": true,
|
| 1214 |
-
"trusted": true
|
| 1215 |
-
},
|
| 1216 |
-
"outputs": [],
|
| 1217 |
-
"source": [
|
| 1218 |
-
"\n",
|
| 1219 |
-
"# nginx 反向代理配置文件\n",
|
| 1220 |
-
"def localProxy():\n",
|
| 1221 |
-
" def getProxyLocation(subPath:str, localServer:str):\n",
|
| 1222 |
-
" return '''\n",
|
| 1223 |
-
" location '''+ subPath +'''\n",
|
| 1224 |
-
" {\n",
|
| 1225 |
-
" proxy_pass '''+ localServer +''';\n",
|
| 1226 |
-
" \n",
|
| 1227 |
-
" client_max_body_size 1000m;\n",
|
| 1228 |
-
" proxy_set_header Host $http_host;\n",
|
| 1229 |
-
" proxy_set_header X-Real-IP $remote_addr;\n",
|
| 1230 |
-
" proxy_set_header X-Real-Port $remote_port;\n",
|
| 1231 |
-
" proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n",
|
| 1232 |
-
" proxy_set_header X-Forwarded-Proto $scheme;\n",
|
| 1233 |
-
" proxy_set_header X-Forwarded-Host $host;\n",
|
| 1234 |
-
" proxy_set_header X-Forwarded-Port $server_port;\n",
|
| 1235 |
-
" proxy_set_header REMOTE-HOST $remote_addr;\n",
|
| 1236 |
-
" proxy_connect_timeout 3000s;\n",
|
| 1237 |
-
" proxy_send_timeout 3000s;\n",
|
| 1238 |
-
" proxy_read_timeout 3000s;\n",
|
| 1239 |
-
" proxy_http_version 1.1;\n",
|
| 1240 |
-
" proxy_set_header Upgrade $http_upgrade;\n",
|
| 1241 |
-
" proxy_set_header Connection 'upgrade';\n",
|
| 1242 |
-
" add_header Access-Control-Allow-Origin * always;\n",
|
| 1243 |
-
" add_header Access-Control-Allow-Headers *;\n",
|
| 1244 |
-
" add_header Access-Control-Allow-Methods \"GET, POST, PUT, OPTIONS\";\n",
|
| 1245 |
-
" }\n",
|
| 1246 |
-
" \n",
|
| 1247 |
-
" '''\n",
|
| 1248 |
-
" \n",
|
| 1249 |
-
" conf = '''\n",
|
| 1250 |
-
"server\n",
|
| 1251 |
-
"{\n",
|
| 1252 |
-
" listen '''+str(_server_port)+''';\n",
|
| 1253 |
-
" listen [::]:'''+str(_server_port)+''';\n",
|
| 1254 |
-
" server_name 127.0.0.1 localhost 0.0.0.0 \"\";\n",
|
| 1255 |
-
" \n",
|
| 1256 |
-
" fastcgi_send_timeout 3000s;\n",
|
| 1257 |
-
" fastcgi_read_timeout 3000s;\n",
|
| 1258 |
-
" fastcgi_connect_timeout 3000s;\n",
|
| 1259 |
-
" \n",
|
| 1260 |
-
" if ($request_method = OPTIONS) {\n",
|
| 1261 |
-
" return 200;\n",
|
| 1262 |
-
" }\n",
|
| 1263 |
-
" \n",
|
| 1264 |
-
" '''+ ''.join([getProxyLocation(key,_proxy_path[key]) for key in sorted(_proxy_path.keys(), key=len)[::-1]]) +'''\n",
|
| 1265 |
-
"}\n",
|
| 1266 |
-
"'''\n",
|
| 1267 |
-
" echoToFile(conf,'/etc/nginx/conf.d/proxy_nginx.conf')\n",
|
| 1268 |
-
" if not check_service('localhost',_server_port):\n",
|
| 1269 |
-
" run(f'''nginx -c /etc/nginx/nginx.conf''')\n",
|
| 1270 |
-
" run(f'''nginx -s reload''')"
|
| 1271 |
-
]
|
| 1272 |
-
},
|
| 1273 |
-
{
|
| 1274 |
-
"cell_type": "markdown",
|
| 1275 |
-
"metadata": {},
|
| 1276 |
-
"source": [
|
| 1277 |
-
"## 线程清理工具\n",
|
| 1278 |
-
"\n",
|
| 1279 |
-
"---\n",
|
| 1280 |
-
"\n",
|
| 1281 |
-
"清理线程名以 solo_ 开头的所有线程"
|
| 1282 |
-
]
|
| 1283 |
-
},
|
| 1284 |
-
{
|
| 1285 |
-
"cell_type": "code",
|
| 1286 |
-
"execution_count": null,
|
| 1287 |
-
"metadata": {
|
| 1288 |
-
"_kg_hide-input": true,
|
| 1289 |
-
"trusted": true
|
| 1290 |
-
},
|
| 1291 |
-
"outputs": [],
|
| 1292 |
-
"source": [
|
| 1293 |
-
"import inspect\n",
|
| 1294 |
-
"import ctypes\n",
|
| 1295 |
-
"\n",
|
| 1296 |
-
"def _async_raise(tid, exctype):\n",
|
| 1297 |
-
" \"\"\"raises the exception, performs cleanup if needed\"\"\"\n",
|
| 1298 |
-
" tid = ctypes.c_long(tid)\n",
|
| 1299 |
-
" if not inspect.isclass(exctype):\n",
|
| 1300 |
-
" exctype = type(exctype)\n",
|
| 1301 |
-
" res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))\n",
|
| 1302 |
-
" if res == 0:\n",
|
| 1303 |
-
" raise ValueError(\"invalid thread id\")\n",
|
| 1304 |
-
" elif res != 1:\n",
|
| 1305 |
-
" # \"\"\"if it returns a number greater than one, you're in trouble,\n",
|
| 1306 |
-
" # and you should call it again with exc=NULL to revert the effect\"\"\"\n",
|
| 1307 |
-
" ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)\n",
|
| 1308 |
-
" raise SystemError(\"PyThreadState_SetAsyncExc failed\")\n",
|
| 1309 |
-
"\n",
|
| 1310 |
-
"def stop_thread(thread):\n",
|
| 1311 |
-
" _async_raise(thread.ident, SystemExit)\n",
|
| 1312 |
-
"\n",
|
| 1313 |
-
"def stop_solo_threads():\n",
|
| 1314 |
-
" global _runing\n",
|
| 1315 |
-
" _runing = False\n",
|
| 1316 |
-
" # 获取当前所有活动的线程\n",
|
| 1317 |
-
" threads = threading.enumerate()\n",
|
| 1318 |
-
" # 关闭之前创建的子线程\n",
|
| 1319 |
-
" for thread in threads:\n",
|
| 1320 |
-
" if thread.name.startswith('solo_'):\n",
|
| 1321 |
-
" print(f'结束线程:{thread.name}')\n",
|
| 1322 |
-
" try:\n",
|
| 1323 |
-
" stop_thread(thread)\n",
|
| 1324 |
-
" except socket.error:\n",
|
| 1325 |
-
" print(f'结束线程:{thread.name} 执行失败')"
|
| 1326 |
-
]
|
| 1327 |
-
},
|
| 1328 |
-
{
|
| 1329 |
-
"cell_type": "markdown",
|
| 1330 |
-
"metadata": {
|
| 1331 |
-
"id": "Ve3p8oOkLCtE"
|
| 1332 |
-
},
|
| 1333 |
-
"source": [
|
| 1334 |
-
"# webui 安装和配置函数\n",
|
| 1335 |
-
"---"
|
| 1336 |
-
]
|
| 1337 |
-
},
|
| 1338 |
-
{
|
| 1339 |
-
"cell_type": "code",
|
| 1340 |
-
"execution_count": null,
|
| 1341 |
-
"metadata": {
|
| 1342 |
-
"_kg_hide-input": true,
|
| 1343 |
-
"id": "GTjyBJihLCtE",
|
| 1344 |
-
"trusted": true
|
| 1345 |
-
},
|
| 1346 |
-
"outputs": [],
|
| 1347 |
-
"source": [
|
| 1348 |
-
"envInstalled=False\n",
|
| 1349 |
-
"quickStart = False\n",
|
| 1350 |
-
"#安装\n",
|
| 1351 |
-
"def install():\n",
|
| 1352 |
-
" print('安装')\n",
|
| 1353 |
-
" os.chdir(f'''{_install_path}''')\n",
|
| 1354 |
-
" run(f'''git lfs install''')\n",
|
| 1355 |
-
" run(f'''git config --global credential.helper store''')\n",
|
| 1356 |
-
" for requirement in requirements:\n",
|
| 1357 |
-
" run(f'pip install {requirement}')\n",
|
| 1358 |
-
" if _reLoad:\n",
|
| 1359 |
-
" run(f'''rm -rf {_install_path}/{_ui_dir_name}''')\n",
|
| 1360 |
-
" if Path(f\"{_ui_dir_name}\").exists():\n",
|
| 1361 |
-
" os.chdir(f'''{_install_path}/{_ui_dir_name}/''')\n",
|
| 1362 |
-
" run(f'''git checkout .''')\n",
|
| 1363 |
-
" run(f'''git pull''')\n",
|
| 1364 |
-
" else:\n",
|
| 1365 |
-
" run(f'''git clone --recursive {_sd_git_repo} {_ui_dir_name}''')\n",
|
| 1366 |
-
" if not Path(f'''{_install_path}/{_ui_dir_name}''').exists():\n",
|
| 1367 |
-
" print('sd-webui主程序安装失败,请检查 sd_git_repo 配置的值是否正确')\n",
|
| 1368 |
-
" sys.exit(0)\n",
|
| 1369 |
-
" os.chdir(f'''{_install_path}/{_ui_dir_name}''')\n",
|
| 1370 |
-
" print('安装 完成')\n",
|
| 1371 |
-
"\n",
|
| 1372 |
-
"# 链接输出目录\n",
|
| 1373 |
-
"def link_dir():\n",
|
| 1374 |
-
" print('链接输出目录')\n",
|
| 1375 |
-
" # 链接图片输出目录\n",
|
| 1376 |
-
" run(f'''mkdir -p {_output_path}/outputs''')\n",
|
| 1377 |
-
" run(f'''rm -rf {_install_path}/{_ui_dir_name}/outputs''')\n",
|
| 1378 |
-
" run(f'''ln -s -r {_output_path}/outputs {_install_path}/{_ui_dir_name}/''')\n",
|
| 1379 |
-
" # 输出收藏目录\n",
|
| 1380 |
-
" run(f'''mkdir -p {_output_path}/log''')\n",
|
| 1381 |
-
" run(f'''rm -rf {_install_path}/{_ui_dir_name}/log''')\n",
|
| 1382 |
-
" run(f'''ln -s -r {_output_path}/log {_install_path}/{_ui_dir_name}/''')\n",
|
| 1383 |
-
" # 链接训练输出目录 文件夹链接会导致功能不能用\n",
|
| 1384 |
-
" run(f'''rm -rf {_install_path}/{_ui_dir_name}/textual_inversion''')\n",
|
| 1385 |
-
" run(f'''mkdir -p {_output_path}/textual_inversion/''')\n",
|
| 1386 |
-
" run(f'''ln -s -r {_output_path}/textual_inversion {_install_path}/{_ui_dir_name}/''')\n",
|
| 1387 |
-
" print('链接输出目录 完成') \n",
|
| 1388 |
-
"\n",
|
| 1389 |
-
"def install_optimizing():\n",
|
| 1390 |
-
" run('add-apt-repository ppa:deadsnakes/ppa -y')\n",
|
| 1391 |
-
" run('apt update -y')\n",
|
| 1392 |
-
" run('apt install nginx -y')\n",
|
| 1393 |
-
" # run('apt install python3.10 -y')\n",
|
| 1394 |
-
" \n",
|
| 1395 |
-
"#安装依赖\n",
|
| 1396 |
-
"def install_dependencies():\n",
|
| 1397 |
-
" print('安装需要的python环境')\n",
|
| 1398 |
-
" global envInstalled\n",
|
| 1399 |
-
" global venvPath\n",
|
| 1400 |
-
" if Path(f'{_install_path}/{_ui_dir_name}/venv').exists():\n",
|
| 1401 |
-
" print('跳过安装python环境')\n",
|
| 1402 |
-
" envInstalled = True\n",
|
| 1403 |
-
" return\n",
|
| 1404 |
-
" \n",
|
| 1405 |
-
" if quickStart:\n",
|
| 1406 |
-
" if not Path(venvPath).exists():\n",
|
| 1407 |
-
" mkdirs(f'{_install_path}/venv_cache',True)\n",
|
| 1408 |
-
" if not Path(f'{_install_path}/venv_cache/venv.tar.bak').exists():\n",
|
| 1409 |
-
" print('下载 venv.zip')\n",
|
| 1410 |
-
" download_file('https://huggingface.co/viyi/sdwui/resolve/main/venv.zip','venv.zip',f'{_install_path}/venv_cache')\n",
|
| 1411 |
-
" run(f'''unzip {_install_path}/venv_cache/venv.zip -d {_install_path}/venv_cache''')\n",
|
| 1412 |
-
" venvPath = f'{_install_path}/venv_cache/venv.tar.bak'\n",
|
| 1413 |
-
" run(f'''rm -rf {_install_path}/venv_cache/venv.zip''')\n",
|
| 1414 |
-
" elif venvPath.endswith('.zip'):\n",
|
| 1415 |
-
" mkdirs(f'{_install_path}/venv_cache',True)\n",
|
| 1416 |
-
" run(f'''unzip {venvPath} -d {_install_path}/venv_cache''')\n",
|
| 1417 |
-
" venvPath = f'{_install_path}/venv_cache/venv.tar.bak'\n",
|
| 1418 |
-
" print('解压环境')\n",
|
| 1419 |
-
" mkdirs(f'{_install_path}/{_ui_dir_name}/venv')\n",
|
| 1420 |
-
"# run('python3.10 -m venv venv',cwd=f'{_install_path}/{_ui_dir_name}')\n",
|
| 1421 |
-
" run(f'tar -xf {venvPath} -C ./venv',cwd=f'{_install_path}/{_ui_dir_name}')\n",
|
| 1422 |
-
" run(f'rm -f {_install_path}/{_ui_dir_name}/venv/bin/pip*')\n",
|
| 1423 |
-
" run(f'rm -f {_install_path}/{_ui_dir_name}/venv/bin/python*')\n",
|
| 1424 |
-
" venv.create(f'{_install_path}/{_ui_dir_name}/venv')\n",
|
| 1425 |
-
" if not Path(f'{_install_path}/{_ui_dir_name}/venv/bin/pip').exists():\n",
|
| 1426 |
-
" run('curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py')\n",
|
| 1427 |
-
" run(f'{_install_path}/{_ui_dir_name}/venv/bin/python3 get-pip.py')\n",
|
| 1428 |
-
"\n",
|
| 1429 |
-
" get_ipython().system(f'''{_install_path}/{_ui_dir_name}/venv/bin/python3 -V''')\n",
|
| 1430 |
-
" get_ipython().system(f'''{_install_path}/{_ui_dir_name}/venv/bin/python3 -m pip -V''')\n",
|
| 1431 |
-
" \n",
|
| 1432 |
-
" # if not quickStart:\n",
|
| 1433 |
-
" # run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python3 -V''')\n",
|
| 1434 |
-
" # run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python3 -m pip -V''')\n",
|
| 1435 |
-
" # run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python -m pip install torch==2.3.1 torchvision==0.18.1 torchaudio==2.3.1 --index-url https://download.pytorch.org/whl/cu121''')\n",
|
| 1436 |
-
" # run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python -m pip install xformers==0.0.27''')\n",
|
| 1437 |
-
" # run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python -m pip install -r requirements_versions.txt''')\n",
|
| 1438 |
-
" # run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python -m pip install spandrel==0.3.0''')\n",
|
| 1439 |
-
" # run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python -m pip install opencv-python''')\n",
|
| 1440 |
-
" # run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python -m pip install pydantic==1.10.15''')\n",
|
| 1441 |
-
" # run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python -m pip install transformers -U''')\n",
|
| 1442 |
-
" # run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python -m pip install llama-cpp-python''')\n",
|
| 1443 |
-
" # run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python -m pip install pytorch_lightning==2.3.3 torchsde==0.2.6 spandrel==0.3.4''')\n",
|
| 1444 |
-
" \n",
|
| 1445 |
-
" # run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python3 -m pip install open-clip-torch -U''')\n",
|
| 1446 |
-
" # run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python3 -m pip install protobuf==4.25.8''')\n",
|
| 1447 |
-
" # run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python3 -m pip install blendmodes==2022''')\n",
|
| 1448 |
-
" # run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python3 -m pip install Pillow==9.5.0''')\n",
|
| 1449 |
-
" # run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python3 -m pip install basicsr''')\n",
|
| 1450 |
-
" \n",
|
| 1451 |
-
" get_ipython().system(f'''{_install_path}/{_ui_dir_name}/venv/bin/python3 -m pip install basicsr wrapt''')\n",
|
| 1452 |
-
" \n",
|
| 1453 |
-
" envInstalled = True\n",
|
| 1454 |
-
" print('安装需要的python环境 完成')\n",
|
| 1455 |
-
" \n",
|
| 1456 |
-
"# 个性化配置 \n",
|
| 1457 |
-
"def use_config():\n",
|
| 1458 |
-
" print('使用自定义配置 包括tag翻译 \\n')\n",
|
| 1459 |
-
" run(f'''mkdir -p {_install_path}/temp''')\n",
|
| 1460 |
-
" run(f'git clone {_sd_config_git_repu} sd-configs',cwd=f'{_install_path}/temp')\n",
|
| 1461 |
-
" run(f'cp -r -f -n {_install_path}/temp/sd-configs/dist/* {_install_path}/{_ui_dir_name}')\n",
|
| 1462 |
-
" if not Path(_ui_config_file).exists() and _ui_config_file != 'ui-config.json': # ui配置文件\n",
|
| 1463 |
-
" run(f'''mkdir -p {_ui_config_file[:_ui_config_file.rfind('/')]}''')\n",
|
| 1464 |
-
" run(f'cp -f -n {_install_path}/{_ui_dir_name}/ui-config.json {_ui_config_file}')\n",
|
| 1465 |
-
" if not Path(_setting_file).exists() and _setting_file != 'config.json': # 设置配置文件\n",
|
| 1466 |
-
" run(f'''mkdir -p {_setting_file[:_setting_file.rfind('/')]}''')\n",
|
| 1467 |
-
" run(f'cp -f -n {_install_path}/{_ui_dir_name}/config.json {_setting_file}')\n",
|
| 1468 |
-
"\n",
|
| 1469 |
-
"def copy_last_log_to_images():\n",
|
| 1470 |
-
" if not Path(f'{_install_path}/{_ui_dir_name}/log/images').exists(): mkdirs(f'{_install_path}/{_ui_dir_name}/log/images')\n",
|
| 1471 |
-
" print('复制编号最大的一张收藏图到输出目录,用于保持编号,否则会出现收藏的图片被覆盖的情况')\n",
|
| 1472 |
-
" img_list = os.listdir(f'{_install_path}/{_ui_dir_name}/log/images')\n",
|
| 1473 |
-
" last_img_path = ''\n",
|
| 1474 |
-
" last_img_num = 0\n",
|
| 1475 |
-
" for img in img_list:\n",
|
| 1476 |
-
" if re.findall(r'^\\d+-',str(img)):\n",
|
| 1477 |
-
" num = int(re.findall(r'^\\d+-',str(img))[0][:-1])\n",
|
| 1478 |
-
" if num > last_img_num:\n",
|
| 1479 |
-
" last_img_path = img\n",
|
| 1480 |
-
" last_img_num = num\n",
|
| 1481 |
-
" \n",
|
| 1482 |
-
" if not last_img_path: return\n",
|
| 1483 |
-
" \n",
|
| 1484 |
-
" print(f'{_install_path}/{_ui_dir_name}/log/images/{last_img_path} {_install_path}/{_ui_dir_name}/outputs/txt2img-images')\n",
|
| 1485 |
-
" run(f'''mkdir -p {_install_path}/{_ui_dir_name}/outputs/txt2img-images''')\n",
|
| 1486 |
-
" run(f'''cp -f {_install_path}/{_ui_dir_name}/log/images/{last_img_path} {_install_path}/{_ui_dir_name}/outputs/txt2img-images/''')\n",
|
| 1487 |
-
" \n",
|
| 1488 |
-
" print(f'{_install_path}/{_ui_dir_name}/log/images/{last_img_path} {_install_path}/{_ui_dir_name}/outputs/img2img-images')\n",
|
| 1489 |
-
" run(f'''mkdir -p {_install_path}/{_ui_dir_name}/outputs/img2img-images''')\n",
|
| 1490 |
-
" run(f'''cp -f {_install_path}/{_ui_dir_name}/log/images/{last_img_path} {_install_path}/{_ui_dir_name}/outputs/img2img-images/''')\n",
|
| 1491 |
-
" \n",
|
| 1492 |
-
"def start_webui(i):\n",
|
| 1493 |
-
" # 只要不爆内存,其他方式关闭后会再次重启 访问地址会发生变化\n",
|
| 1494 |
-
" print(i,'--port',str(_server_port+1+i))\n",
|
| 1495 |
-
" if i>0:\n",
|
| 1496 |
-
" print(f'使用第{i+1}张显卡启动第{i+1}个服务,通过frpc或nrgok地址后加{_sub_path[i]}进行访问')\n",
|
| 1497 |
-
"\n",
|
| 1498 |
-
" current_thread = threading.current_thread()\n",
|
| 1499 |
-
" current_thread.name = f\"solo_webui__{i}\"\n",
|
| 1500 |
-
" \n",
|
| 1501 |
-
" restart_times = 0\n",
|
| 1502 |
-
" last_restart_time = time.time()\n",
|
| 1503 |
-
" while _runing:\n",
|
| 1504 |
-
" os.chdir(f'{_install_path}/{_ui_dir_name}')\n",
|
| 1505 |
-
" root_path = _sub_path[i]\n",
|
| 1506 |
-
" if root_path.endswith('/'): root_path = root_path[:-1]\n",
|
| 1507 |
-
" if torch.cuda.device_count() == 1 or not _multi_case:\n",
|
| 1508 |
-
" get_ipython().system(f'''venv/bin/python3 launch.py --port {str(_server_port+1+i)} --subpath={_sub_path[i]}''')\n",
|
| 1509 |
-
" else: \n",
|
| 1510 |
-
" get_ipython().system(f'''venv/bin/python3 launch.py --device-id={i} --port {str(_server_port+1+i)} --subpath={_sub_path[i]}''')\n",
|
| 1511 |
-
" print('10秒后重启服务')\n",
|
| 1512 |
-
" if time.time() - last_restart_time < 60:\n",
|
| 1513 |
-
" restart_times = restart_times + 1\n",
|
| 1514 |
-
" else:\n",
|
| 1515 |
-
" restart_times = 0\n",
|
| 1516 |
-
" last_restart_time = time.time()\n",
|
| 1517 |
-
" if restart_times >3 :\n",
|
| 1518 |
-
" # 如果180秒内重启了3此,将不再自动重启\n",
|
| 1519 |
-
" break\n",
|
| 1520 |
-
" time.sleep(10)\n",
|
| 1521 |
-
" \n",
|
| 1522 |
-
"# 启动\n",
|
| 1523 |
-
"def start():\n",
|
| 1524 |
-
" print('启动webui')\n",
|
| 1525 |
-
" os.chdir(f'''{_install_path}/{_ui_dir_name}''')\n",
|
| 1526 |
-
" args = ''\n",
|
| 1527 |
-
" if _ui_config_file is not None and _ui_config_file != '' and Path(_ui_config_file).exists(): # ui配置文件\n",
|
| 1528 |
-
" args += ' --ui-config-file=' + _ui_config_file\n",
|
| 1529 |
-
" if _setting_file is not None and _setting_file != '' and Path(_setting_file).exists(): # 设置配置文件\n",
|
| 1530 |
-
" args += ' --ui-settings-file=' + _setting_file\n",
|
| 1531 |
-
" args += ' ' + otherArgs\n",
|
| 1532 |
-
" os.environ['COMMANDLINE_ARGS']=args\n",
|
| 1533 |
-
" run(f'''echo COMMANDLINE_ARGS=$COMMANDLINE_ARGS''')\n",
|
| 1534 |
-
" os.environ['REQS_FILE']='requirements_versions.txt'\n",
|
| 1535 |
-
"\n",
|
| 1536 |
-
" with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:\n",
|
| 1537 |
-
" for i in range(torch.cuda.device_count() if _multi_case else 1):\n",
|
| 1538 |
-
" executor.submit(start_webui,i)\n",
|
| 1539 |
-
" while _runing and not check_service('localhost',str(_server_port+1+i)): # 当当前服务启动完成才允许退出此次循环\n",
|
| 1540 |
-
" time.sleep(5)\n",
|
| 1541 |
-
" if not _runing: break\n",
|
| 1542 |
-
" time.sleep(10)"
|
| 1543 |
-
]
|
| 1544 |
-
},
|
| 1545 |
-
{
|
| 1546 |
-
"cell_type": "markdown",
|
| 1547 |
-
"metadata": {
|
| 1548 |
-
"id": "qLvsk8ByLCtF"
|
| 1549 |
-
},
|
| 1550 |
-
"source": [
|
| 1551 |
-
"# 入口函数\n",
|
| 1552 |
-
"---"
|
| 1553 |
-
]
|
| 1554 |
-
},
|
| 1555 |
-
{
|
| 1556 |
-
"cell_type": "code",
|
| 1557 |
-
"execution_count": null,
|
| 1558 |
-
"metadata": {
|
| 1559 |
-
"_kg_hide-input": true,
|
| 1560 |
-
"id": "IOKjaMlcLCtF",
|
| 1561 |
-
"trusted": true
|
| 1562 |
-
},
|
| 1563 |
-
"outputs": [],
|
| 1564 |
-
"source": [
|
| 1565 |
-
"\n",
|
| 1566 |
-
"# 启动非webui相关的的内容,加快启动速度\n",
|
| 1567 |
-
"def main():\n",
|
| 1568 |
-
" global envInstalled\n",
|
| 1569 |
-
" global huggingface_is_init\n",
|
| 1570 |
-
" global _runing\n",
|
| 1571 |
-
" _init_conf()\n",
|
| 1572 |
-
" stop_solo_threads()\n",
|
| 1573 |
-
" print('启动...')\n",
|
| 1574 |
-
" startTicks = time.time()\n",
|
| 1575 |
-
" time.sleep(5)\n",
|
| 1576 |
-
" _runing = True\n",
|
| 1577 |
-
" isInstall = True if os.getenv('IsInstall','False') == 'True' else False\n",
|
| 1578 |
-
" _proxy_path[_sub_path[0]] = f'http://127.0.0.1:{_server_port+1}/'\n",
|
| 1579 |
-
" _proxy_path[_sub_path[1]] = f'http://127.0.0.1:{_server_port+2}/'\n",
|
| 1580 |
-
" proxy_thread = threading.Thread(target = startProxy, daemon=True, name='solo_startProxy')\n",
|
| 1581 |
-
" proxy_thread.start()\n",
|
| 1582 |
-
" if isInstall is False or _reLoad: \n",
|
| 1583 |
-
" print('安装运行环境')\n",
|
| 1584 |
-
" os.environ['MPLBACKEND'] = 'Agg'\n",
|
| 1585 |
-
" install()\n",
|
| 1586 |
-
" link_dir()\n",
|
| 1587 |
-
" init_huggingface()\n",
|
| 1588 |
-
" install_optimizing()\n",
|
| 1589 |
-
" if not _skip_webui:\n",
|
| 1590 |
-
" threading.Thread(target = install_dependencies,daemon=True,name='solo_install_dependencies').start()\n",
|
| 1591 |
-
" else: envInstalled = True\n",
|
| 1592 |
-
" link_or_download_flie(replace_path(_async_downloading), _link_instead_of_copy=_link_instead_of_copy,\n",
|
| 1593 |
-
" base_path=f'{_install_path}/{_ui_dir_name}')\n",
|
| 1594 |
-
" if huggingface_is_init:\n",
|
| 1595 |
-
" threading.Thread(target = download__huggingface_repo,daemon=True,\n",
|
| 1596 |
-
" args=([_huggingface_repo]),\n",
|
| 1597 |
-
" kwargs={\"callback\":copy_last_log_to_images},\n",
|
| 1598 |
-
" name='solo_download__huggingface_repo').start()\n",
|
| 1599 |
-
" \n",
|
| 1600 |
-
" link_or_download_flie(replace_path(_before_downloading), _link_instead_of_copy=_link_instead_of_copy,\n",
|
| 1601 |
-
" base_path=f'{_install_path}/{_ui_dir_name}',is_await=True,sync=True)\n",
|
| 1602 |
-
" t = 0\n",
|
| 1603 |
-
" while _runing and not envInstalled:\n",
|
| 1604 |
-
" if t%10==0:\n",
|
| 1605 |
-
" print('等待python环境安装...')\n",
|
| 1606 |
-
" t = t+1\n",
|
| 1607 |
-
" time.sleep(1)\n",
|
| 1608 |
-
" use_config()\n",
|
| 1609 |
-
" os.environ['IsInstall'] = 'True'\n",
|
| 1610 |
-
" else:\n",
|
| 1611 |
-
" envInstalled = True\n",
|
| 1612 |
-
" localProxy()\n",
|
| 1613 |
-
" link_or_download_flie(replace_path(_before_start_sync_downloading), _link_instead_of_copy=_link_instead_of_copy,\n",
|
| 1614 |
-
" base_path=f'{_install_path}/{_ui_dir_name}',sync=True)\n",
|
| 1615 |
-
" if init_huggingface():\n",
|
| 1616 |
-
" start_sync_log_to_huggingface(_huggingface_repo)\n",
|
| 1617 |
-
" ticks = time.time()\n",
|
| 1618 |
-
" _on_before_start()\n",
|
| 1619 |
-
" print(\"加载耗时:\",(ticks - startTicks),\"秒\")\n",
|
| 1620 |
-
" if _skip_webui:\n",
|
| 1621 |
-
" print('跳过webui启动')\n",
|
| 1622 |
-
" proxy_thread.join()\n",
|
| 1623 |
-
" else:\n",
|
| 1624 |
-
" start()\n"
|
| 1625 |
-
]
|
| 1626 |
-
},
|
| 1627 |
-
{
|
| 1628 |
-
"cell_type": "markdown",
|
| 1629 |
-
"metadata": {
|
| 1630 |
-
"id": "0oaCRs2gLCtF"
|
| 1631 |
-
},
|
| 1632 |
-
"source": [
|
| 1633 |
-
"# 执行区域\n",
|
| 1634 |
-
"---"
|
| 1635 |
-
]
|
| 1636 |
-
},
|
| 1637 |
-
{
|
| 1638 |
-
"cell_type": "code",
|
| 1639 |
-
"execution_count": null,
|
| 1640 |
-
"metadata": {
|
| 1641 |
-
"_kg_hide-output": true,
|
| 1642 |
-
"id": "O3DR0DWHLCtF",
|
| 1643 |
-
"scrolled": true,
|
| 1644 |
-
"trusted": true
|
| 1645 |
-
},
|
| 1646 |
-
"outputs": [],
|
| 1647 |
-
"source": [
|
| 1648 |
-
"# 启动\n",
|
| 1649 |
-
"# _reLoad = True\n",
|
| 1650 |
-
"# hidden_console_info = False\n",
|
| 1651 |
-
"# run_by_none_device = True\n",
|
| 1652 |
-
"# show_shell_info = True\n",
|
| 1653 |
-
"\n",
|
| 1654 |
-
"print(f'当前sd的安装路径是:{_install_path}/{_ui_dir_name}')\n",
|
| 1655 |
-
"print(f'当前图片保存路径是:{_output_path}')\n",
|
| 1656 |
-
"print(f'当前数据集路径是:{_input_path}')\n",
|
| 1657 |
-
"\n",
|
| 1658 |
-
"print(update_desc)\n",
|
| 1659 |
-
"\n",
|
| 1660 |
-
"if _skip_start:\n",
|
| 1661 |
-
" print('已跳过自动启动,可手动执行 main() 进行启动。')\n",
|
| 1662 |
-
" print('''推荐的启动代码:\n",
|
| 1663 |
-
"try:\n",
|
| 1664 |
-
" check_gpu() # 检查是否存在gpu\n",
|
| 1665 |
-
" main()\n",
|
| 1666 |
-
"except KeyboardInterrupt:\n",
|
| 1667 |
-
" stop_solo_threads() # 中断后自动停止后台线程 (有部分功能在后台线程中运行)\n",
|
| 1668 |
-
" ''')\n",
|
| 1669 |
-
"else:\n",
|
| 1670 |
-
" try:\n",
|
| 1671 |
-
" check_gpu()\n",
|
| 1672 |
-
" main()\n",
|
| 1673 |
-
" except KeyboardInterrupt:\n",
|
| 1674 |
-
" stop_solo_threads()"
|
| 1675 |
-
]
|
| 1676 |
-
},
|
| 1677 |
-
{
|
| 1678 |
-
"cell_type": "code",
|
| 1679 |
-
"execution_count": null,
|
| 1680 |
-
"metadata": {
|
| 1681 |
-
"trusted": true
|
| 1682 |
-
},
|
| 1683 |
-
"outputs": [],
|
| 1684 |
-
"source": []
|
| 1685 |
-
}
|
| 1686 |
-
],
|
| 1687 |
-
"metadata": {
|
| 1688 |
-
"kaggle": {
|
| 1689 |
-
"accelerator": "nvidiaTeslaT4",
|
| 1690 |
-
"dataSources": [
|
| 1691 |
-
{
|
| 1692 |
-
"datasetId": 2716934,
|
| 1693 |
-
"sourceId": 6167400,
|
| 1694 |
-
"sourceType": "datasetVersion"
|
| 1695 |
-
},
|
| 1696 |
-
{
|
| 1697 |
-
"datasetId": 3654544,
|
| 1698 |
-
"sourceId": 6346544,
|
| 1699 |
-
"sourceType": "datasetVersion"
|
| 1700 |
-
},
|
| 1701 |
-
{
|
| 1702 |
-
"datasetId": 2962375,
|
| 1703 |
-
"sourceId": 6720235,
|
| 1704 |
-
"sourceType": "datasetVersion"
|
| 1705 |
-
},
|
| 1706 |
-
{
|
| 1707 |
-
"datasetId": 3074484,
|
| 1708 |
-
"sourceId": 6817788,
|
| 1709 |
-
"sourceType": "datasetVersion"
|
| 1710 |
-
}
|
| 1711 |
-
],
|
| 1712 |
-
"isGpuEnabled": true,
|
| 1713 |
-
"isInternetEnabled": true,
|
| 1714 |
-
"language": "python",
|
| 1715 |
-
"sourceType": "notebook"
|
| 1716 |
-
},
|
| 1717 |
-
"kernelspec": {
|
| 1718 |
-
"display_name": "Python 3",
|
| 1719 |
-
"language": "python",
|
| 1720 |
-
"name": "python3"
|
| 1721 |
-
},
|
| 1722 |
-
"language_info": {
|
| 1723 |
-
"codemirror_mode": {
|
| 1724 |
-
"name": "ipython",
|
| 1725 |
-
"version": 3
|
| 1726 |
-
},
|
| 1727 |
-
"file_extension": ".py",
|
| 1728 |
-
"mimetype": "text/x-python",
|
| 1729 |
-
"name": "python",
|
| 1730 |
-
"nbconvert_exporter": "python",
|
| 1731 |
-
"pygments_lexer": "ipython3",
|
| 1732 |
-
"version": "3.10.13"
|
| 1733 |
-
}
|
| 1734 |
-
},
|
| 1735 |
-
"nbformat": 4,
|
| 1736 |
-
"nbformat_minor": 4
|
| 1737 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sdwui-start-util.ipynb
DELETED
|
@@ -1,1735 +0,0 @@
|
|
| 1 |
-
{
|
| 2 |
-
"cells": [
|
| 3 |
-
{
|
| 4 |
-
"cell_type": "code",
|
| 5 |
-
"execution_count": null,
|
| 6 |
-
"metadata": {
|
| 7 |
-
"trusted": true
|
| 8 |
-
},
|
| 9 |
-
"outputs": [],
|
| 10 |
-
"source": []
|
| 11 |
-
},
|
| 12 |
-
{
|
| 13 |
-
"cell_type": "code",
|
| 14 |
-
"execution_count": null,
|
| 15 |
-
"metadata": {
|
| 16 |
-
"trusted": true
|
| 17 |
-
},
|
| 18 |
-
"outputs": [],
|
| 19 |
-
"source": [
|
| 20 |
-
"update_desc = '''\n",
|
| 21 |
-
"欢迎使用 stable-diffusion-webui 便捷启动工具\n",
|
| 22 |
-
"\n",
|
| 23 |
-
"此脚本理论上可以在任何jupyter环境运行,但仅在 google colab 和 kaggle 测试。 已经无法在 google colab 免费实例上运行。\n",
|
| 24 |
-
"此脚本的【前置脚本】发布地址 https://www.kaggle.com/code/yiyiooo/stable-diffusion-webui-novelai-sdxl。\n",
|
| 25 |
-
"此脚本需配合 【前置脚本】 的脚本附带的配置项才能正常启动。\n",
|
| 26 |
-
"此脚本的内容会自动更新,你无需更新【前置脚本】就能获取到最新的功能。\n",
|
| 27 |
-
"增加一个说明:为解决加密图片的解密和浏览的问题,开发了一个独立应用,可以在这里下载 https://github.com/viyiviyi/encrypt_gallery/releases/\n",
|
| 28 |
-
"加密插件可解决生成nsfw图片后被平台封号问题\n",
|
| 29 |
-
"\n",
|
| 30 |
-
"路径说明\n",
|
| 31 |
-
"* 为了解决平台差异,所有的安装目录和文件输出目录都被重新指定,如果你需要在配置中访问这些目录,请查看以下说明\n",
|
| 32 |
-
"*\n",
|
| 33 |
-
"* 可以使用 $install_path 或 {install_path} 来访问安装目录,写在字符串内也会生效\n",
|
| 34 |
-
"* $output_path 或 {output_path} 可以访问输出目录\n",
|
| 35 |
-
"* 如果你需要安装在自定义目录,也可以设置这些值 如: install_path = '新的路径'\n",
|
| 36 |
-
"* 可自定义方法 on_before_start 并在方法内写上启动前需要的逻辑来实现在webui启动前执行自定义逻辑\n",
|
| 37 |
-
"* 可以增加配置 multi_case = True 来控制是否使用多卡\n",
|
| 38 |
-
"* 如果需要显示更多控制台输出 需配置 hidden_console_info = False\n",
|
| 39 |
-
"\n",
|
| 40 |
-
"********* 特别提示 *********\n",
|
| 41 |
-
"* huggingface 的下载链接需要增加 ?download=true 参数才能正确下载到文件,如果你需要的文件里的下载链接没有这个参数,请自行增加。\n",
|
| 42 |
-
"'''"
|
| 43 |
-
]
|
| 44 |
-
},
|
| 45 |
-
{
|
| 46 |
-
"cell_type": "code",
|
| 47 |
-
"execution_count": null,
|
| 48 |
-
"metadata": {
|
| 49 |
-
"trusted": true
|
| 50 |
-
},
|
| 51 |
-
"outputs": [],
|
| 52 |
-
"source": [
|
| 53 |
-
"from pathlib import Path\n",
|
| 54 |
-
"import os\n",
|
| 55 |
-
"import time\n",
|
| 56 |
-
"import re\n",
|
| 57 |
-
"import subprocess\n",
|
| 58 |
-
"import threading\n",
|
| 59 |
-
"import sys\n",
|
| 60 |
-
"import socket\n",
|
| 61 |
-
"import torch\n",
|
| 62 |
-
"from typing import List\n",
|
| 63 |
-
"import uuid\n",
|
| 64 |
-
"import asyncio\n",
|
| 65 |
-
"from urllib import request"
|
| 66 |
-
]
|
| 67 |
-
},
|
| 68 |
-
{
|
| 69 |
-
"cell_type": "code",
|
| 70 |
-
"execution_count": null,
|
| 71 |
-
"metadata": {
|
| 72 |
-
"trusted": true
|
| 73 |
-
},
|
| 74 |
-
"outputs": [],
|
| 75 |
-
"source": [
|
| 76 |
-
"# 内置参数默认值,当上下文有参数时可覆盖默认值\n",
|
| 77 |
-
"_runing = False\n",
|
| 78 |
-
"\n",
|
| 79 |
-
"_useFrpc = locals().get('useFrpc') or globals().get('useFrpc') or True\n",
|
| 80 |
-
"\n",
|
| 81 |
-
"_useNgrok = locals().get('useNgrok') or globals().get('useNgrok') or True\n",
|
| 82 |
-
"\n",
|
| 83 |
-
"_reLoad = locals().get('reLoad') or globals().get('reLoad') or False\n",
|
| 84 |
-
" \n",
|
| 85 |
-
"_before_downloading = locals().get('before_downloading') or globals().get('before_downloading') or ''\n",
|
| 86 |
-
"\n",
|
| 87 |
-
"_async_downloading = locals().get('async_downloading') or globals().get('async_downloading') or ''\n",
|
| 88 |
-
"\n",
|
| 89 |
-
"_before_start_sync_downloading = locals().get('before_start_sync_downloading') or globals().get('before_start_sync_downloading') or ''\n",
|
| 90 |
-
"\n",
|
| 91 |
-
"_server_port = locals().get('server_port') or globals().get('server_port') or 7860\n",
|
| 92 |
-
" \n",
|
| 93 |
-
"_sd_git_repo = locals().get('sd_git_repo') or globals().get('sd_git_repo') or 'https://github.com/viyiviyi/stable-diffusion-webui.git -b local' \n",
|
| 94 |
-
"_sd_git_repo = _sd_git_repo\\\n",
|
| 95 |
-
" .replace('{sdwui}','stable-diffusion-webui')\\\n",
|
| 96 |
-
" .replace('{wui}',\"webui\")\n",
|
| 97 |
-
" \n",
|
| 98 |
-
"_sd_config_git_repu = locals().get('sd_config_git_repu') or globals().get('sd_config_git_repu') or 'https://github.com/viyiviyi/sd-configs.git'\n",
|
| 99 |
-
"_sd_config_git_repu = _sd_config_git_repu\\\n",
|
| 100 |
-
" .replace('{sdwui}','stable-diffusion-webui')\\\n",
|
| 101 |
-
" .replace('{wui}',\"webui\")\n",
|
| 102 |
-
" \n",
|
| 103 |
-
" \n",
|
| 104 |
-
"_huggingface_token = locals().get('huggingface_token') or globals().get('huggingface_token') or '{input_path}/configs/huggingface_token.txt'\n",
|
| 105 |
-
"_huggingface_token = _huggingface_token\\\n",
|
| 106 |
-
" .replace('{sdwui}','stable-diffusion-webui')\\\n",
|
| 107 |
-
" .replace('{wui}',\"webui\")\n",
|
| 108 |
-
" \n",
|
| 109 |
-
"_huggingface_repo = locals().get('huggingface_repo') or globals().get('huggingface_repo') or ''\n",
|
| 110 |
-
"_huggingface_repo = _huggingface_repo\\\n",
|
| 111 |
-
" .replace('{sdwui}','stable-diffusion-webui')\\\n",
|
| 112 |
-
" .replace('{wui}',\"webui\")\n",
|
| 113 |
-
"\n",
|
| 114 |
-
"_link_instead_of_copy = locals().get('link_instead_of_copy') or globals().get('link_instead_of_copy') or True\n",
|
| 115 |
-
" \n",
|
| 116 |
-
"show_shell_info = locals().get('hidden_console_info') or globals().get('hidden_console_info')\n",
|
| 117 |
-
"if show_shell_info is None: show_shell_info = False\n",
|
| 118 |
-
"else: show_shell_info = not show_shell_info\n",
|
| 119 |
-
"\n",
|
| 120 |
-
"_multi_case = locals().get('multi_case') or globals().get('multi_case') or False\n",
|
| 121 |
-
" \n",
|
| 122 |
-
"_skip_start = locals().get('skip_start') or globals().get('skip_start') or True\n",
|
| 123 |
-
"\n",
|
| 124 |
-
"def before_start():\n",
|
| 125 |
-
" pass\n",
|
| 126 |
-
"\n",
|
| 127 |
-
"def main_start():\n",
|
| 128 |
-
" pass\n",
|
| 129 |
-
"\n",
|
| 130 |
-
"_on_before_start = locals().get('on_before_start') or globals().get('on_before_start') or before_start \n",
|
| 131 |
-
"_skip_webui = locals().get('skip_webui') or globals().get('skip_webui') or False\n",
|
| 132 |
-
" \n",
|
| 133 |
-
"run_by_none_device = False\n",
|
| 134 |
-
"\n",
|
| 135 |
-
"_proxy_path = locals().get('proxy_path') or globals().get('proxy_path') or {}\n",
|
| 136 |
-
"\n",
|
| 137 |
-
"_sub_path = locals().get('sub_path') or globals().get('sub_path') or ['/','/1/']\n",
|
| 138 |
-
"if len(_sub_path) != 2:\n",
|
| 139 |
-
" _sub_path = ['/','/1/']\n",
|
| 140 |
-
" \n",
|
| 141 |
-
"_config_args:dict[str, str] = locals().get('config_args') or globals().get('config_args') or {}"
|
| 142 |
-
]
|
| 143 |
-
},
|
| 144 |
-
{
|
| 145 |
-
"cell_type": "code",
|
| 146 |
-
"execution_count": null,
|
| 147 |
-
"metadata": {
|
| 148 |
-
"trusted": true
|
| 149 |
-
},
|
| 150 |
-
"outputs": [],
|
| 151 |
-
"source": [
|
| 152 |
-
"\n",
|
| 153 |
-
"def run(command, cwd=None, desc=None, errdesc=None, custom_env=None,try_error:bool=True) -> str:\n",
|
| 154 |
-
" global show_shell_info\n",
|
| 155 |
-
" if desc is not None:\n",
|
| 156 |
-
" print(desc)\n",
|
| 157 |
-
"\n",
|
| 158 |
-
" run_kwargs = {\n",
|
| 159 |
-
" \"args\": command,\n",
|
| 160 |
-
" \"shell\": True,\n",
|
| 161 |
-
" \"cwd\": cwd,\n",
|
| 162 |
-
" \"env\": os.environ if custom_env is None else custom_env,\n",
|
| 163 |
-
" \"encoding\": 'utf8',\n",
|
| 164 |
-
" \"errors\": 'ignore',\n",
|
| 165 |
-
" }\n",
|
| 166 |
-
"\n",
|
| 167 |
-
" if not show_shell_info:\n",
|
| 168 |
-
" run_kwargs[\"stdout\"] = run_kwargs[\"stderr\"] = subprocess.PIPE\n",
|
| 169 |
-
"\n",
|
| 170 |
-
" result = subprocess.run(**run_kwargs)\n",
|
| 171 |
-
"\n",
|
| 172 |
-
" if result.returncode != 0:\n",
|
| 173 |
-
" error_bits = [\n",
|
| 174 |
-
" f\"{errdesc or 'Error running command'}.\",\n",
|
| 175 |
-
" f\"Command: {command}\",\n",
|
| 176 |
-
" f\"Error code: {result.returncode}\",\n",
|
| 177 |
-
" ]\n",
|
| 178 |
-
" if result.stdout:\n",
|
| 179 |
-
" error_bits.append(f\"stdout: {result.stdout}\")\n",
|
| 180 |
-
" if result.stderr:\n",
|
| 181 |
-
" error_bits.append(f\"stderr: {result.stderr}\")\n",
|
| 182 |
-
" if try_error:\n",
|
| 183 |
-
" print((RuntimeError(\"\\n\".join(error_bits))))\n",
|
| 184 |
-
" else:\n",
|
| 185 |
-
" raise RuntimeError(\"\\n\".join(error_bits))\n",
|
| 186 |
-
"\n",
|
| 187 |
-
" if show_shell_info:\n",
|
| 188 |
-
" print((result.stdout or \"\"))\n",
|
| 189 |
-
" return (result.stdout or \"\")\n",
|
| 190 |
-
"\n",
|
| 191 |
-
"def mkdirs(path, exist_ok=True):\n",
|
| 192 |
-
" if path and not Path(path).exists():\n",
|
| 193 |
-
" os.makedirs(path,exist_ok=exist_ok)\n",
|
| 194 |
-
"\n",
|
| 195 |
-
"\n",
|
| 196 |
-
"# 检查网络\n",
|
| 197 |
-
"def check_service(host, port):\n",
|
| 198 |
-
" try:\n",
|
| 199 |
-
" socket.create_connection((host, port), timeout=5)\n",
|
| 200 |
-
" return True\n",
|
| 201 |
-
" except socket.error:\n",
|
| 202 |
-
" return False\n",
|
| 203 |
-
"\n",
|
| 204 |
-
"\n",
|
| 205 |
-
"# 检查gpu是否存在\n",
|
| 206 |
-
"def check_gpu():\n",
|
| 207 |
-
" if not run_by_none_device and torch.cuda.device_count() == 0:\n",
|
| 208 |
-
" raise Exception('当前环境没有GPU')\n",
|
| 209 |
-
"\n",
|
| 210 |
-
"\n",
|
| 211 |
-
"def echoToFile(content:str,path:str):\n",
|
| 212 |
-
" if path.find('/') >= 0:\n",
|
| 213 |
-
" _path = '/'.join(path.split('/')[:-1])\n",
|
| 214 |
-
" run(f'''mkdir -p {_path}''')\n",
|
| 215 |
-
" with open(path,'w') as sh:\n",
|
| 216 |
-
" sh.write(content)\n",
|
| 217 |
-
" \n",
|
| 218 |
-
"def get_freefrp_confog(local_port):\n",
|
| 219 |
-
" rd_str = uuid.uuid1()\n",
|
| 220 |
-
" return (f'''\n",
|
| 221 |
-
"[common]\n",
|
| 222 |
-
"server_addr = frp.freefrp.net\n",
|
| 223 |
-
"server_port = 7000\n",
|
| 224 |
-
"token = freefrp.net\n",
|
| 225 |
-
"\n",
|
| 226 |
-
"[{rd_str}_http]\n",
|
| 227 |
-
"type = http\n",
|
| 228 |
-
"local_ip = 127.0.0.1\n",
|
| 229 |
-
"local_port = {local_port}\n",
|
| 230 |
-
"custom_domains = {rd_str}.frp.eaias.com\n",
|
| 231 |
-
"''',f'http://{rd_str}.frp.eaias.com')"
|
| 232 |
-
]
|
| 233 |
-
},
|
| 234 |
-
{
|
| 235 |
-
"cell_type": "code",
|
| 236 |
-
"execution_count": null,
|
| 237 |
-
"metadata": {
|
| 238 |
-
"trusted": true
|
| 239 |
-
},
|
| 240 |
-
"outputs": [],
|
| 241 |
-
"source": [
|
| 242 |
-
"\n",
|
| 243 |
-
"_install_path = f\"/kaggle\" if os.path.exists('/kaggle/') else f\"{os.environ['HOME']}/sd_webui\" # 安装目录\n",
|
| 244 |
-
"_output_path = '/kaggle/working' if os.path.exists('/kaggle/working/') else f\"{os.environ['HOME']}/.sdwui/Output\" # 输出目录 如果使用google云盘 会在google云盘增加sdwebui/Output\n",
|
| 245 |
-
"_input_path = '/kaggle/input' # 输入目录\n",
|
| 246 |
-
"_ui_dir_name = 'sd_main_dir'\n",
|
| 247 |
-
"\n",
|
| 248 |
-
"_install_path = locals().get('install_path') or globals().get('install_path') or _install_path\n",
|
| 249 |
-
"_output_path = locals().get('output_path') or globals().get('output_path') or _output_path\n",
|
| 250 |
-
"_input_path = locals().get('input_path') or globals().get('input_path') or _input_path\n",
|
| 251 |
-
"_ui_dir_name = locals().get('ui_dir_name') or globals().get('ui_dir_name') or _ui_dir_name\n",
|
| 252 |
-
"\n",
|
| 253 |
-
"install_path = _install_path\n",
|
| 254 |
-
"output_path = _output_path\n",
|
| 255 |
-
"input_path = _input_path\n",
|
| 256 |
-
"ui_dir_name = _ui_dir_name\n",
|
| 257 |
-
" \n",
|
| 258 |
-
"google_drive = '' \n",
|
| 259 |
-
"\n",
|
| 260 |
-
"\n",
|
| 261 |
-
"_useGooglrDrive = locals().get('useGooglrDrive') or globals().get('useGooglrDrive') or True\n",
|
| 262 |
-
"\n",
|
| 263 |
-
"# 连接谷歌云\n",
|
| 264 |
-
"try:\n",
|
| 265 |
-
" if _useGooglrDrive:\n",
|
| 266 |
-
" from google.colab import drive\n",
|
| 267 |
-
" drive.mount(f'~/google_drive')\n",
|
| 268 |
-
" google_drive = f\"{os.environ['HOME']}/google_drive/MyDrive\"\n",
|
| 269 |
-
" _output_path = f'{google_drive}/sdwebui/Output'\n",
|
| 270 |
-
" _input_path = f'{google_drive}/sdwebui/Input'\n",
|
| 271 |
-
" run(f'''mkdir -p {_input_path}''')\n",
|
| 272 |
-
" print('''\n",
|
| 273 |
-
"已经链接到谷歌云盘\n",
|
| 274 |
-
"已在云盘创建Input和Output目录\n",
|
| 275 |
-
" ''')\n",
|
| 276 |
-
"except:\n",
|
| 277 |
-
" _useGooglrDrive = False\n",
|
| 278 |
-
"\n",
|
| 279 |
-
"run(f'''mkdir -p {_install_path}''')\n",
|
| 280 |
-
"run(f'''mkdir -p {_output_path}''')\n",
|
| 281 |
-
"\n",
|
| 282 |
-
"\n",
|
| 283 |
-
"os.environ['install_path'] = _install_path\n",
|
| 284 |
-
"os.environ['output_path'] = _output_path\n",
|
| 285 |
-
"os.environ['google_drive'] = google_drive\n",
|
| 286 |
-
"os.environ['input_path'] = _input_path\n",
|
| 287 |
-
"\n",
|
| 288 |
-
"def replace_path(input_str:str):\n",
|
| 289 |
-
" if not input_str: return ''\n",
|
| 290 |
-
" for key in _config_args:\n",
|
| 291 |
-
" input_str = input_str.replace(key,_config_args[key])\n",
|
| 292 |
-
" \n",
|
| 293 |
-
" if not (locals().get('use_comfyui') or globals().get('use_comfyui') or False):\n",
|
| 294 |
-
" input_str = input_str.replace('https://github.com/comfyanonymous/ComfyUI.git','https://github.com/comfyanonymous/ComfyUI.git')\n",
|
| 295 |
-
" \n",
|
| 296 |
-
" return input_str.replace('$install_path',_install_path)\\\n",
|
| 297 |
-
" .replace('{install_path}',_install_path)\\\n",
|
| 298 |
-
" .replace('$input_path',_input_path)\\\n",
|
| 299 |
-
" .replace('{input_path}',_input_path)\\\n",
|
| 300 |
-
" .replace('$output_path',_output_path)\\\n",
|
| 301 |
-
" .replace('{output_path}',_output_path)\\\n",
|
| 302 |
-
" .replace('{sdwui}','stable-diffusion-webui')\\\n",
|
| 303 |
-
" .replace('{wui}',\"webui\")\n",
|
| 304 |
-
"\n",
|
| 305 |
-
"space_string = ' \\n\\r\\t\\'\\\",'\n",
|
| 306 |
-
"\n",
|
| 307 |
-
"def config_reader(conf:str):\n",
|
| 308 |
-
" conf = conf or \"\"\n",
|
| 309 |
-
" args = [replace_path(item.split('#')[0].strip(space_string)) for item in conf.split('\\n') if item.strip(space_string)]\n",
|
| 310 |
-
" return [item.strip() for item in args if item.strip()]\n"
|
| 311 |
-
]
|
| 312 |
-
},
|
| 313 |
-
{
|
| 314 |
-
"cell_type": "code",
|
| 315 |
-
"execution_count": null,
|
| 316 |
-
"metadata": {
|
| 317 |
-
"_kg_hide-input": true,
|
| 318 |
-
"id": "i3LhnwYHLCtC",
|
| 319 |
-
"trusted": true
|
| 320 |
-
},
|
| 321 |
-
"outputs": [],
|
| 322 |
-
"source": [
|
| 323 |
-
"ngrokTokenFile = os.path.join(_input_path,'configs/ngrok_token.txt') # 非必填 存放ngrokToken的文件的路径\n",
|
| 324 |
-
"frpcConfigFile = os.path.join(_input_path,'configs/frpc_koishi.ini') # 非必填 frp 配置文件\n",
|
| 325 |
-
"# ss证书目录 下载nginx的版本,把pem格式改成crt格式\n",
|
| 326 |
-
"frpcSSLFFlies = [os.path.join(_input_path,'configs/koishi_ssl')]\n",
|
| 327 |
-
"if 'frp_ssl_dir' in locals() or 'frp_ssl_dir' in globals():\n",
|
| 328 |
-
" frpcSSLFFlies = frpcSSLFFlies + config_reader(locals().get('frp_ssl_dir') or globals().get('frp_ssl_dir'))\n",
|
| 329 |
-
"# frpc 文件目录 如果目录不存在,会自动下载,也可以在数据集搜索 viyiviyi/utils 添加\n",
|
| 330 |
-
"frpcExePath = os.path.join(_input_path,'utils-tools/frpc')\n",
|
| 331 |
-
"# 其他需要加载的webui启动参数 写到【参数列表】这个配置去\n",
|
| 332 |
-
"otherArgs = '--xformers'\n",
|
| 333 |
-
"if 'sd_start_args' in locals() or 'sd_start_args' in globals():\n",
|
| 334 |
-
" otherArgs = ' '.join([item for item in config_reader(locals().get('sd_start_args') or globals().get('sd_start_args')) if item != '--no-gradio-queue'])\n",
|
| 335 |
-
"venvPath = os.path.join(_input_path,'sd-webui-venv/venv.tar.bak') # 安装好的python环境 sd-webui-venv是一个公开是数据集 可以搜索添加\n",
|
| 336 |
-
"\n",
|
| 337 |
-
"# 用于使用kaggle api的token文件 参考 https://www.kaggle.com/docs/api\n",
|
| 338 |
-
"# 此文件用于自动上传koishi的相关配置 也可以用于保存重要的输出文件\n",
|
| 339 |
-
"kaggleApiTokenFile = os.path.join(_input_path,'configs/kaggle.json')\n",
|
| 340 |
-
"\n",
|
| 341 |
-
"requirements = []\n"
|
| 342 |
-
]
|
| 343 |
-
},
|
| 344 |
-
{
|
| 345 |
-
"cell_type": "code",
|
| 346 |
-
"execution_count": null,
|
| 347 |
-
"metadata": {
|
| 348 |
-
"_kg_hide-input": true,
|
| 349 |
-
"id": "a_GtG2ayLCtD",
|
| 350 |
-
"trusted": true
|
| 351 |
-
},
|
| 352 |
-
"outputs": [],
|
| 353 |
-
"source": [
|
| 354 |
-
"# 这下面的是用于初始化一些值或者环境变量的,轻易别改\n",
|
| 355 |
-
"_setting_file = replace_path(locals().get('setting_file') or globals().get('setting_file') or 'config.json')\n",
|
| 356 |
-
"\n",
|
| 357 |
-
"_ui_config_file = replace_path(locals().get('ui_config_file') or globals().get('ui_config_file') or 'ui-config.json')\n",
|
| 358 |
-
"\n",
|
| 359 |
-
"# 设置文件路径\n",
|
| 360 |
-
"if Path(f\"{os.environ['HOME']}/google_drive/MyDrive\").exists():\n",
|
| 361 |
-
" if _setting_file == '/kaggle/working/configs/config.json':\n",
|
| 362 |
-
" _setting_file = os.path.join(_output_path,'configs/config.json')\n",
|
| 363 |
-
" if _ui_config_file == '/kaggle/working/configs/ui-config.json':\n",
|
| 364 |
-
" _ui_config_file = os.path.join(_output_path,'configs/ui-config.json')\n",
|
| 365 |
-
" \n",
|
| 366 |
-
"frpcStartArg = ''\n",
|
| 367 |
-
"freefrp_url = ''\n",
|
| 368 |
-
"_frp_temp_config_file = ''\n",
|
| 369 |
-
"_frp_config_or_file = replace_path(locals().get('frp_config_or_file') or globals().get('frp_config_or_file')) or frpcConfigFile\n",
|
| 370 |
-
"run(f'''mkdir -p {_install_path}/configFiles''')\n",
|
| 371 |
-
"if _frp_config_or_file:\n",
|
| 372 |
-
" if '[common]' in _frp_config_or_file:\n",
|
| 373 |
-
" echoToFile(_frp_config_or_file,f'{_install_path}/configFiles/temp_frpc_webui.ini')\n",
|
| 374 |
-
" _frp_temp_config_file = f'{_install_path}/configFiles/temp_frpc_webui.ini'\n",
|
| 375 |
-
" elif '.ini' in _frp_config_or_file:\n",
|
| 376 |
-
" _frp_temp_config_file = _frp_config_or_file.strip()\n",
|
| 377 |
-
" \n",
|
| 378 |
-
" if _frp_temp_config_file:\n",
|
| 379 |
-
" if Path(_frp_temp_config_file).exists():\n",
|
| 380 |
-
" run(f'''cp -f {_frp_temp_config_file} {_install_path}/configFiles/frpc_webui.ini''')\n",
|
| 381 |
-
" run(f'''sed -i \"s/local_port = .*/local_port = {_server_port}/g\" {_install_path}/configFiles/frpc_webui.ini''')\n",
|
| 382 |
-
" frpcStartArg = f' -c {_install_path}/configFiles/frpc_webui.ini'\n",
|
| 383 |
-
" elif _frp_config_or_file.strip().startswith('-f'):\n",
|
| 384 |
-
" frpcStartArg = _frp_config_or_file.strip()\n",
|
| 385 |
-
" \n",
|
| 386 |
-
"if not frpcStartArg:\n",
|
| 387 |
-
" conf,url = get_freefrp_confog(_server_port)\n",
|
| 388 |
-
" echoToFile(conf,f'{_install_path}/configFiles/frpc_webui.ini')\n",
|
| 389 |
-
" freefrp_url = url\n",
|
| 390 |
-
" frpcStartArg = f' -c {_install_path}/configFiles/frpc_webui.ini'\n",
|
| 391 |
-
"\n",
|
| 392 |
-
"ngrokToken=''\n",
|
| 393 |
-
"_ngrok_config_or_file = replace_path(locals().get('ngrok_config_or_file') or globals().get('ngrok_config_or_file')) or ngrokTokenFile\n",
|
| 394 |
-
"if _ngrok_config_or_file:\n",
|
| 395 |
-
" if Path(_ngrok_config_or_file.strip()).exists():\n",
|
| 396 |
-
" ngrokTokenFile = _ngrok_config_or_file.strip()\n",
|
| 397 |
-
" if Path(ngrokTokenFile).exists():\n",
|
| 398 |
-
" with open(ngrokTokenFile,encoding = \"utf-8\") as nkfile:\n",
|
| 399 |
-
" ngrokToken = nkfile.readline()\n",
|
| 400 |
-
" elif not _ngrok_config_or_file.strip().startswith('/'):\n",
|
| 401 |
-
" ngrokToken=_ngrok_config_or_file.strip()\n",
|
| 402 |
-
" \n",
|
| 403 |
-
"if not Path(venvPath).exists():\n",
|
| 404 |
-
" venvPath = os.path.join(_input_path,'sd-webui-venv/venv.zip')\n",
|
| 405 |
-
" \n",
|
| 406 |
-
"huggingface_headers:dict = None "
|
| 407 |
-
]
|
| 408 |
-
},
|
| 409 |
-
{
|
| 410 |
-
"cell_type": "code",
|
| 411 |
-
"execution_count": null,
|
| 412 |
-
"metadata": {},
|
| 413 |
-
"outputs": [],
|
| 414 |
-
"source": [
|
| 415 |
-
"def _init_conf():\n",
|
| 416 |
-
" global _useFrpc\n",
|
| 417 |
-
" global _useNgrok\n",
|
| 418 |
-
" global _reLoad\n",
|
| 419 |
-
" global _before_downloading\n",
|
| 420 |
-
" global _async_downloading\n",
|
| 421 |
-
" global _before_start_sync_downloading\n",
|
| 422 |
-
" global _server_port\n",
|
| 423 |
-
" global _sd_git_repo\n",
|
| 424 |
-
" global _sd_config_git_repu\n",
|
| 425 |
-
" global _huggingface_token\n",
|
| 426 |
-
" global _huggingface_repo\n",
|
| 427 |
-
" global _link_instead_of_copy\n",
|
| 428 |
-
" global show_shell_info\n",
|
| 429 |
-
" global _multi_case\n",
|
| 430 |
-
" global _skip_start\n",
|
| 431 |
-
" global _on_before_start\n",
|
| 432 |
-
" global _skip_webui\n",
|
| 433 |
-
" global _proxy_path\n",
|
| 434 |
-
" global _sub_path\n",
|
| 435 |
-
" global _config_args\n",
|
| 436 |
-
" global _install_path\n",
|
| 437 |
-
" global _output_path\n",
|
| 438 |
-
" global _input_path\n",
|
| 439 |
-
" global _ui_dir_name\n",
|
| 440 |
-
" \n",
|
| 441 |
-
" global ngrokTokenFile\n",
|
| 442 |
-
" global frpcConfigFile\n",
|
| 443 |
-
" global frpcSSLFFlies\n",
|
| 444 |
-
" global frpcExePath\n",
|
| 445 |
-
" global otherArgs\n",
|
| 446 |
-
" global _setting_file\n",
|
| 447 |
-
" global _ui_config_file\n",
|
| 448 |
-
" global _frp_temp_config_file\n",
|
| 449 |
-
" global _frp_config_or_file\n",
|
| 450 |
-
" global ngrokToken\n",
|
| 451 |
-
" global venvPath\n",
|
| 452 |
-
" \n",
|
| 453 |
-
" _useFrpc = locals().get('useFrpc') or globals().get('useFrpc') or True\n",
|
| 454 |
-
" _useNgrok = locals().get('useNgrok') or globals().get('useNgrok') or True\n",
|
| 455 |
-
" _reLoad = locals().get('reLoad') or globals().get('reLoad') or False\n",
|
| 456 |
-
" _before_downloading = locals().get('before_downloading') or globals().get('before_downloading') or ''\n",
|
| 457 |
-
" _async_downloading = locals().get('async_downloading') or globals().get('async_downloading') or ''\n",
|
| 458 |
-
" _before_start_sync_downloading = locals().get('before_start_sync_downloading') or globals().get('before_start_sync_downloading') or ''\n",
|
| 459 |
-
" _server_port = locals().get('server_port') or globals().get('server_port') or 7860\n",
|
| 460 |
-
" _sd_git_repo = locals().get('sd_git_repo') or globals().get('sd_git_repo') or 'https://github.com/viyiviyi/stable-diffusion-webui.git -b local' \n",
|
| 461 |
-
" _sd_git_repo = _sd_git_repo\\\n",
|
| 462 |
-
" .replace('{sdwui}','stable-diffusion-webui')\\\n",
|
| 463 |
-
" .replace('{wui}',\"webui\") \n",
|
| 464 |
-
" _sd_config_git_repu = locals().get('sd_config_git_repu') or globals().get('sd_config_git_repu') or 'https://github.com/viyiviyi/sd-configs.git'\n",
|
| 465 |
-
" _sd_config_git_repu = _sd_config_git_repu\\\n",
|
| 466 |
-
" .replace('{sdwui}','stable-diffusion-webui')\\\n",
|
| 467 |
-
" .replace('{wui}',\"webui\")\n",
|
| 468 |
-
" _huggingface_token = locals().get('huggingface_token') or globals().get('huggingface_token') or '{input_path}/configs/huggingface_token.txt'\n",
|
| 469 |
-
" _huggingface_token = _huggingface_token\\\n",
|
| 470 |
-
" .replace('{sdwui}','stable-diffusion-webui')\\\n",
|
| 471 |
-
" .replace('{wui}',\"webui\")\n",
|
| 472 |
-
" _huggingface_repo = locals().get('huggingface_repo') or globals().get('huggingface_repo') or ''\n",
|
| 473 |
-
" _huggingface_repo = _huggingface_repo\\\n",
|
| 474 |
-
" .replace('{sdwui}','stable-diffusion-webui')\\\n",
|
| 475 |
-
" .replace('{wui}',\"webui\")\n",
|
| 476 |
-
" _link_instead_of_copy = locals().get('link_instead_of_copy') or globals().get('link_instead_of_copy') or True\n",
|
| 477 |
-
" show_shell_info = locals().get('hidden_console_info') or globals().get('hidden_console_info')\n",
|
| 478 |
-
" if show_shell_info is None: show_shell_info = False\n",
|
| 479 |
-
" else: show_shell_info = not show_shell_info\n",
|
| 480 |
-
" _multi_case = locals().get('multi_case') or globals().get('multi_case') or False\n",
|
| 481 |
-
" _skip_start = locals().get('skip_start') or globals().get('skip_start') or True\n",
|
| 482 |
-
" _on_before_start = locals().get('on_before_start') or globals().get('on_before_start') or before_start \n",
|
| 483 |
-
" _skip_webui = locals().get('skip_webui') or globals().get('skip_webui') or False\n",
|
| 484 |
-
" _proxy_path = locals().get('proxy_path') or globals().get('proxy_path') or {}\n",
|
| 485 |
-
" _sub_path = locals().get('sub_path') or globals().get('sub_path') or ['/','/1/']\n",
|
| 486 |
-
" if len(_sub_path) != 2:\n",
|
| 487 |
-
" _sub_path = ['/','/1/']\n",
|
| 488 |
-
" \n",
|
| 489 |
-
" _config_args = locals().get('config_args') or globals().get('config_args') or {}\n",
|
| 490 |
-
" \n",
|
| 491 |
-
" _install_path = locals().get('install_path') or globals().get('install_path') or _install_path\n",
|
| 492 |
-
" _output_path = locals().get('output_path') or globals().get('output_path') or _output_path\n",
|
| 493 |
-
" _input_path = locals().get('input_path') or globals().get('input_path') or _input_path\n",
|
| 494 |
-
" _ui_dir_name = locals().get('ui_dir_name') or globals().get('ui_dir_name') or _ui_dir_name\n",
|
| 495 |
-
" \n",
|
| 496 |
-
" ngrokTokenFile = os.path.join(_input_path,'configs/ngrok_token.txt') # 非必填 存放ngrokToken的文件的路径\n",
|
| 497 |
-
" frpcConfigFile = os.path.join(_input_path,'configs/frpc_koishi.ini') # 非必填 frp 配置文件\n",
|
| 498 |
-
" # ss证书目录 下载nginx的版本,把pem格式改成crt格式\n",
|
| 499 |
-
" frpcSSLFFlies = [os.path.join(_input_path,'configs/koishi_ssl')]\n",
|
| 500 |
-
" if 'frp_ssl_dir' in locals() or 'frp_ssl_dir' in globals():\n",
|
| 501 |
-
" frpcSSLFFlies = frpcSSLFFlies + config_reader(locals().get('frp_ssl_dir') or globals().get('frp_ssl_dir'))\n",
|
| 502 |
-
" # frpc 文件目录 如果目录不存在,会自动下载,也可以在数据集搜索 viyiviyi/utils 添加\n",
|
| 503 |
-
" frpcExePath = os.path.join(_input_path,'utils-tools/frpc')\n",
|
| 504 |
-
" # 其他需要加载的webui启动参数 写到【参数列表】这个配置去\n",
|
| 505 |
-
" otherArgs = '--xformers'\n",
|
| 506 |
-
" if 'sd_start_args' in locals() or 'sd_start_args' in globals():\n",
|
| 507 |
-
" otherArgs = ' '.join([item for item in config_reader(locals().get('sd_start_args') or globals().get('sd_start_args')) if item != '--no-gradio-queue'])\n",
|
| 508 |
-
"\n",
|
| 509 |
-
" # 这下面的是用于初始化一些值或者环境变量的,轻易别改\n",
|
| 510 |
-
" _setting_file = replace_path(locals().get('setting_file') or globals().get('setting_file') or 'config.json')\n",
|
| 511 |
-
"\n",
|
| 512 |
-
" _ui_config_file = replace_path(locals().get('ui_config_file') or globals().get('ui_config_file') or 'ui-config.json')\n",
|
| 513 |
-
"\n",
|
| 514 |
-
" # 设置文件路径\n",
|
| 515 |
-
" if Path(f\"{os.environ['HOME']}/google_drive/MyDrive\").exists():\n",
|
| 516 |
-
" if _setting_file == '/kaggle/working/configs/config.json':\n",
|
| 517 |
-
" _setting_file = os.path.join(_output_path,'configs/config.json')\n",
|
| 518 |
-
" if _ui_config_file == '/kaggle/working/configs/ui-config.json':\n",
|
| 519 |
-
" _ui_config_file = os.path.join(_output_path,'configs/ui-config.json')\n",
|
| 520 |
-
" \n",
|
| 521 |
-
" frpcStartArg = ''\n",
|
| 522 |
-
" freefrp_url = ''\n",
|
| 523 |
-
" _frp_temp_config_file = ''\n",
|
| 524 |
-
" _frp_config_or_file = replace_path(locals().get('frp_config_or_file') or globals().get('frp_config_or_file')) or frpcConfigFile\n",
|
| 525 |
-
" run(f'''mkdir -p {_install_path}/configFiles''')\n",
|
| 526 |
-
" if _frp_config_or_file:\n",
|
| 527 |
-
" if '[common]' in _frp_config_or_file:\n",
|
| 528 |
-
" echoToFile(_frp_config_or_file,f'{_install_path}/configFiles/temp_frpc_webui.ini')\n",
|
| 529 |
-
" _frp_temp_config_file = f'{_install_path}/configFiles/temp_frpc_webui.ini'\n",
|
| 530 |
-
" elif '.ini' in _frp_config_or_file:\n",
|
| 531 |
-
" _frp_temp_config_file = _frp_config_or_file.strip()\n",
|
| 532 |
-
" \n",
|
| 533 |
-
" if _frp_temp_config_file:\n",
|
| 534 |
-
" if Path(_frp_temp_config_file).exists():\n",
|
| 535 |
-
" run(f'''cp -f {_frp_temp_config_file} {_install_path}/configFiles/frpc_webui.ini''')\n",
|
| 536 |
-
" run(f'''sed -i \"s/local_port = .*/local_port = {_server_port}/g\" {_install_path}/configFiles/frpc_webui.ini''')\n",
|
| 537 |
-
" frpcStartArg = f' -c {_install_path}/configFiles/frpc_webui.ini'\n",
|
| 538 |
-
" elif _frp_config_or_file.strip().startswith('-f'):\n",
|
| 539 |
-
" frpcStartArg = _frp_config_or_file.strip()\n",
|
| 540 |
-
" \n",
|
| 541 |
-
" if not frpcStartArg:\n",
|
| 542 |
-
" conf,url = get_freefrp_confog(_server_port)\n",
|
| 543 |
-
" echoToFile(conf,f'{_install_path}/configFiles/frpc_webui.ini')\n",
|
| 544 |
-
" freefrp_url = url\n",
|
| 545 |
-
" frpcStartArg = f' -c {_install_path}/configFiles/frpc_webui.ini'\n",
|
| 546 |
-
"\n",
|
| 547 |
-
" ngrokToken=''\n",
|
| 548 |
-
" _ngrok_config_or_file = replace_path(locals().get('ngrok_config_or_file') or globals().get('ngrok_config_or_file')) or ngrokTokenFile\n",
|
| 549 |
-
" if _ngrok_config_or_file:\n",
|
| 550 |
-
" if Path(_ngrok_config_or_file.strip()).exists():\n",
|
| 551 |
-
" ngrokTokenFile = _ngrok_config_or_file.strip()\n",
|
| 552 |
-
" if Path(ngrokTokenFile).exists():\n",
|
| 553 |
-
" with open(ngrokTokenFile,encoding = \"utf-8\") as nkfile:\n",
|
| 554 |
-
" ngrokToken = nkfile.readline()\n",
|
| 555 |
-
" elif not _ngrok_config_or_file.strip().startswith('/'):\n",
|
| 556 |
-
" ngrokToken=_ngrok_config_or_file.strip()\n",
|
| 557 |
-
" \n",
|
| 558 |
-
" if not Path(venvPath).exists():\n",
|
| 559 |
-
" venvPath = os.path.join(_input_path,'sd-webui-venv/venv.zip')\n",
|
| 560 |
-
" "
|
| 561 |
-
]
|
| 562 |
-
},
|
| 563 |
-
{
|
| 564 |
-
"cell_type": "markdown",
|
| 565 |
-
"metadata": {},
|
| 566 |
-
"source": [
|
| 567 |
-
"## 文件下载工具\n",
|
| 568 |
-
"\n",
|
| 569 |
-
"---\n",
|
| 570 |
-
"\n",
|
| 571 |
-
"link_or_download_flie(config:str, skip_url:bool=False, _link_instead_of_copy:bool=True, base_path:str = '',sync:bool=False,thread_num:int=None)"
|
| 572 |
-
]
|
| 573 |
-
},
|
| 574 |
-
{
|
| 575 |
-
"cell_type": "code",
|
| 576 |
-
"execution_count": null,
|
| 577 |
-
"metadata": {
|
| 578 |
-
"trusted": true
|
| 579 |
-
},
|
| 580 |
-
"outputs": [],
|
| 581 |
-
"source": [
|
| 582 |
-
"import concurrent.futures\n",
|
| 583 |
-
"import importlib\n",
|
| 584 |
-
"import os\n",
|
| 585 |
-
"import pprint\n",
|
| 586 |
-
"import re\n",
|
| 587 |
-
"import venv\n",
|
| 588 |
-
"from pathlib import Path\n",
|
| 589 |
-
"from typing import List\n",
|
| 590 |
-
"\n",
|
| 591 |
-
"import requests\n",
|
| 592 |
-
"\n",
|
| 593 |
-
"show_shell_info = False\n",
|
| 594 |
-
"\n",
|
| 595 |
-
"def is_installed(package):\n",
|
| 596 |
-
" try:\n",
|
| 597 |
-
" spec = importlib.util.find_spec(package)\n",
|
| 598 |
-
" except ModuleNotFoundError:\n",
|
| 599 |
-
" return False\n",
|
| 600 |
-
"\n",
|
| 601 |
-
" return spec is not None\n",
|
| 602 |
-
"\n",
|
| 603 |
-
"def download_file(url:str, filename:str, dist_path:str, cache_path = '',_link_instead_of_copy:bool=True,headers={}):\n",
|
| 604 |
-
" startTicks = time.time()\n",
|
| 605 |
-
" # 获取文件的真实文件名\n",
|
| 606 |
-
" if not filename:\n",
|
| 607 |
-
" with requests.get(url, stream=True,headers=headers) as r:\n",
|
| 608 |
-
" if 'Content-Disposition' in r.headers:\n",
|
| 609 |
-
" filename = r.headers['Content-Disposition'].split('filename=')[1].strip('\"')\n",
|
| 610 |
-
" r.close()\n",
|
| 611 |
-
" if not filename and re.search(r'/[^/]+\\.[^/]+$',url):\n",
|
| 612 |
-
" filename = url.split('/')[-1].split('?')[0]\n",
|
| 613 |
-
" \n",
|
| 614 |
-
" filename = re.sub(r'[\\\\/:*?\"<>|;]', '', filename)\n",
|
| 615 |
-
" filename = re.sub(r'[\\s\\t]+', '_', filename)\n",
|
| 616 |
-
" \n",
|
| 617 |
-
" print(f'下载 {filename} url: {url} --> {dist_path}')\n",
|
| 618 |
-
" \n",
|
| 619 |
-
" # 创建目录\n",
|
| 620 |
-
" if cache_path and not Path(cache_path).exists():\n",
|
| 621 |
-
" os.makedirs(cache_path,exist_ok=True)\n",
|
| 622 |
-
" if dist_path and not Path(dist_path).exists():\n",
|
| 623 |
-
" os.makedirs(dist_path,exist_ok=True)\n",
|
| 624 |
-
" \n",
|
| 625 |
-
" # 拼接文件的完整路径\n",
|
| 626 |
-
" filepath = os.path.join(dist_path, filename)\n",
|
| 627 |
-
"\n",
|
| 628 |
-
" if cache_path:\n",
|
| 629 |
-
" cache_path = os.path.join(cache_path, filename)\n",
|
| 630 |
-
" \n",
|
| 631 |
-
" # 判断文件是否已存在\n",
|
| 632 |
-
" if Path(filepath).exists():\n",
|
| 633 |
-
" print(f'文件 {filename} 已存在 {dist_path}')\n",
|
| 634 |
-
" return\n",
|
| 635 |
-
" \n",
|
| 636 |
-
" if cache_path and Path(cache_path).exists():\n",
|
| 637 |
-
" run(f'cp -n -r -f {\"-s\" if _link_instead_of_copy else \"\"} {cache_path} {dist_path}')\n",
|
| 638 |
-
" print(f'文件缓存 {cache_path} --> {dist_path}')\n",
|
| 639 |
-
" return\n",
|
| 640 |
-
" # 下载文件\n",
|
| 641 |
-
" size = 0\n",
|
| 642 |
-
" with requests.get(url, stream=True, headers=headers) as r:\n",
|
| 643 |
-
" r.raise_for_status()\n",
|
| 644 |
-
" with open(cache_path or filepath, 'wb') as f:\n",
|
| 645 |
-
" for chunk in r.iter_content(chunk_size=1024*1024):\n",
|
| 646 |
-
" if chunk:\n",
|
| 647 |
-
" size += len(chunk)\n",
|
| 648 |
-
" f.write(chunk)\n",
|
| 649 |
-
" # 如果使用了缓存目录 需要复制或链接文件到目标目录\n",
|
| 650 |
-
" if cache_path:\n",
|
| 651 |
-
" run(f'cp -n -r -f {\"-s\" if _link_instead_of_copy else \"\"} {cache_path} {dist_path}')\n",
|
| 652 |
-
" ticks = time.time()\n",
|
| 653 |
-
" print(f'下载完成 {filename} --> {dist_path} 大小{round(size/1024/1024,2)}M 耗时:{round(ticks - startTicks,2)}秒')\n",
|
| 654 |
-
" \n",
|
| 655 |
-
"def download_git(url, dist_path, cache_path = '',_link_instead_of_copy:bool=True):\n",
|
| 656 |
-
" if not Path(dist_path).exists():\n",
|
| 657 |
-
" os.makedirs(dist_path,exist_ok=True)\n",
|
| 658 |
-
" if show_shell_info:\n",
|
| 659 |
-
" print(f'git 下载 {url} --> {dist_path}')\n",
|
| 660 |
-
" if cache_path and not Path(cache_path).exists():\n",
|
| 661 |
-
" os.makedirs(cache_path,exist_ok=True)\n",
|
| 662 |
-
" run(f'git clone {url}',cwd = cache_path)\n",
|
| 663 |
-
" if cache_path:\n",
|
| 664 |
-
" run(f'cp -n -r -f {cache_path}/* {dist_path}')\n",
|
| 665 |
-
" else:\n",
|
| 666 |
-
" run(f'git clone {url}',cwd = dist_path)\n",
|
| 667 |
-
" if show_shell_info:\n",
|
| 668 |
-
" print(f'git 下载完成 {url} --> {dist_path}')\n",
|
| 669 |
-
" \n",
|
| 670 |
-
" \n",
|
| 671 |
-
"def download_huggingface(url:str, filename:str, dist_path, cache_path = '',_link_instead_of_copy:bool=True):\n",
|
| 672 |
-
" fileReg = r'^https:\\/\\/huggingface.co(\\/([^\\/]+\\/)?[^\\/]+\\/[^\\/]+\\/(resolve|blob)\\/[^\\/]+\\/|[^\\.]+\\.[^\\.]+$|download=true)'\n",
|
| 673 |
-
" def isFile(url:str):\n",
|
| 674 |
-
" if re.match(fileReg,url):\n",
|
| 675 |
-
" return True\n",
|
| 676 |
-
" return False\n",
|
| 677 |
-
" if isFile(url):\n",
|
| 678 |
-
" download_file(url,filename,dist_path,cache_path,_link_instead_of_copy,headers=huggingface_headers)\n",
|
| 679 |
-
" else:\n",
|
| 680 |
-
" download_git(url,dist_path,cache_path,_link_instead_of_copy)\n",
|
| 681 |
-
" \n",
|
| 682 |
-
"# 加入文件到下载列表\n",
|
| 683 |
-
"def pause_url(url:str,dist_path:str):\n",
|
| 684 |
-
" file_name = ''\n",
|
| 685 |
-
" if re.match(r'^[^:]+:(https?|ftps?)://', url, flags=0):\n",
|
| 686 |
-
" file_name = re.findall(r'^[^:]+:',url)[0][:-1]\n",
|
| 687 |
-
" url = url[len(file_name)+1:]\n",
|
| 688 |
-
" if not re.match(r'^(https?|ftps?)://',url):\n",
|
| 689 |
-
" return\n",
|
| 690 |
-
" file_name = re.sub(r'\\s+','_',file_name or '')\n",
|
| 691 |
-
" path_hash = str(hash(url)).replace('-','')\n",
|
| 692 |
-
" \n",
|
| 693 |
-
" return {'file_name':file_name,'path_hash':path_hash,'url':url,'dist_path':dist_path}\n",
|
| 694 |
-
"\n",
|
| 695 |
-
"def download_urls(download_list:List[dict],sync:bool=False,thread_num:int=5, \n",
|
| 696 |
-
" cache_path:str=os.path.join(os.environ['HOME'],'.cache','download_util'),\n",
|
| 697 |
-
" _link_instead_of_copy:bool=True,is_await:bool=False):\n",
|
| 698 |
-
" if sync:\n",
|
| 699 |
-
" for conf in download_list:\n",
|
| 700 |
-
" cache_dir = os.path.join(cache_path,conf['path_hash'])\n",
|
| 701 |
-
" if conf['url'].startswith('https://github.com'):\n",
|
| 702 |
-
" try:\n",
|
| 703 |
-
" download_git(conf['url'],conf['dist_path'],cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy)\n",
|
| 704 |
-
" except:\n",
|
| 705 |
-
" pass\n",
|
| 706 |
-
" continue\n",
|
| 707 |
-
" if conf['url'].startswith('https://huggingface.co'):\n",
|
| 708 |
-
" try:\n",
|
| 709 |
-
" download_huggingface(conf['url'],conf['file_name'],conf['dist_path'],cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy)\n",
|
| 710 |
-
" except:\n",
|
| 711 |
-
" pass\n",
|
| 712 |
-
" continue\n",
|
| 713 |
-
" if conf['url'].startswith('https://civitai.com'):\n",
|
| 714 |
-
" if not re.search(r'token=.+', conf['url']):\n",
|
| 715 |
-
" if conf['url'].find('?') == -1:\n",
|
| 716 |
-
" conf['url'] = conf['url']+'?token=fee8bb78b75566eddfd04d061996185c'\n",
|
| 717 |
-
" else:\n",
|
| 718 |
-
" conf['url'] = conf['url']+'&token=fee8bb78b75566eddfd04d061996185c'\n",
|
| 719 |
-
" try:\n",
|
| 720 |
-
" download_file(conf['url'],conf['file_name'],conf['dist_path'],cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy)\n",
|
| 721 |
-
" except:\n",
|
| 722 |
-
" pass\n",
|
| 723 |
-
" else:\n",
|
| 724 |
-
" executor = concurrent.futures.ThreadPoolExecutor(max_workers=thread_num)\n",
|
| 725 |
-
" futures = []\n",
|
| 726 |
-
" for conf in download_list:\n",
|
| 727 |
-
" cache_dir = os.path.join(cache_path,conf['path_hash'])\n",
|
| 728 |
-
" if conf['url'].startswith('https://github.com'):\n",
|
| 729 |
-
" futures.append(executor.submit(download_git, conf['url'],conf['dist_path'],\n",
|
| 730 |
-
" cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy))\n",
|
| 731 |
-
" continue\n",
|
| 732 |
-
" if conf['url'].startswith('https://huggingface.co'):\n",
|
| 733 |
-
" futures.append(executor.submit(download_huggingface,conf['url'],conf['file_name'],conf['dist_path'],cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy))\n",
|
| 734 |
-
" continue\n",
|
| 735 |
-
" if conf['url'].startswith('https://civitai.com'):\n",
|
| 736 |
-
" if not re.search(r'token=.+', conf['url']):\n",
|
| 737 |
-
" if conf['url'].find('?') == -1:\n",
|
| 738 |
-
" conf['url'] = conf['url']+'?token=fee8bb78b75566eddfd04d061996185c'\n",
|
| 739 |
-
" else:\n",
|
| 740 |
-
" conf['url'] = conf['url']+'&token=fee8bb78b75566eddfd04d061996185c'\n",
|
| 741 |
-
" futures.append(executor.submit(download_file, conf['url'],conf['file_name'],conf['dist_path'],\n",
|
| 742 |
-
" cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy))\n",
|
| 743 |
-
" if is_await:\n",
|
| 744 |
-
" concurrent.futures.wait(futures)\n",
|
| 745 |
-
" \n",
|
| 746 |
-
" \n",
|
| 747 |
-
"def parse_config(config:str):\n",
|
| 748 |
-
" space_string = ' \\n\\r\\t\\'\\\",'\n",
|
| 749 |
-
" other_flie_list = [item.split('#')[0].strip(space_string) for item in config.split('\\n') if item.strip(space_string)]\n",
|
| 750 |
-
" other_flie_list = [item.strip() for item in other_flie_list if item.strip()]\n",
|
| 751 |
-
" other_flie_list_store = {}\n",
|
| 752 |
-
" other_flie_list_store_name='default'\n",
|
| 753 |
-
" other_flie_list_store_list_cache=[]\n",
|
| 754 |
-
" \n",
|
| 755 |
-
" for item in other_flie_list:\n",
|
| 756 |
-
" if item.startswith('[') and item.endswith(']'):\n",
|
| 757 |
-
" if not other_flie_list_store_name == 'default':\n",
|
| 758 |
-
" other_flie_list_store[other_flie_list_store_name]=other_flie_list_store_list_cache\n",
|
| 759 |
-
" other_flie_list_store_list_cache = []\n",
|
| 760 |
-
" other_flie_list_store_name = item[1:-1]\n",
|
| 761 |
-
" else:\n",
|
| 762 |
-
" other_flie_list_store_list_cache.append(item)\n",
|
| 763 |
-
" other_flie_list_store[other_flie_list_store_name]=other_flie_list_store_list_cache\n",
|
| 764 |
-
" \n",
|
| 765 |
-
" return other_flie_list_store\n",
|
| 766 |
-
"\n",
|
| 767 |
-
"\n",
|
| 768 |
-
"def link_or_download_flie(config:str, skip_url:bool=False, _link_instead_of_copy:bool=True, base_path:str = '',\n",
|
| 769 |
-
" sync:bool=False,thread_num:int=None, is_await:bool=False):\n",
|
| 770 |
-
" store:dict[str,List[str]] = parse_config(config)\n",
|
| 771 |
-
" download_list = []\n",
|
| 772 |
-
" for dist_dir in store.keys():\n",
|
| 773 |
-
" dist_path = os.path.join(base_path,dist_dir)\n",
|
| 774 |
-
" os.makedirs(dist_path,exist_ok=True)\n",
|
| 775 |
-
" for path in store[dist_dir]:\n",
|
| 776 |
-
" if 'https://' in path or 'http://' in path:\n",
|
| 777 |
-
" if skip_url:\n",
|
| 778 |
-
" continue\n",
|
| 779 |
-
" if sync:\n",
|
| 780 |
-
" try:\n",
|
| 781 |
-
" download_urls([pause_url(path,dist_path)],_link_instead_of_copy = _link_instead_of_copy, sync=sync)\n",
|
| 782 |
-
" except:\n",
|
| 783 |
-
" pass\n",
|
| 784 |
-
" continue\n",
|
| 785 |
-
" download_list.append(pause_url(path,dist_path))\n",
|
| 786 |
-
" else:\n",
|
| 787 |
-
" run(f'cp -n -r -f {\"-s\" if _link_instead_of_copy else \"\"} {path} {dist_path}')\n",
|
| 788 |
-
" if show_shell_info:\n",
|
| 789 |
-
" print(f'{\"链接\" if _link_instead_of_copy else \"复制\"} {path} --> {dist_path}')\n",
|
| 790 |
-
" run(f'rm -f {dist_path}/\\*.* ')\n",
|
| 791 |
-
" if not skip_url:\n",
|
| 792 |
-
" if show_shell_info:\n",
|
| 793 |
-
" pprint.pprint(download_list)\n",
|
| 794 |
-
" try:\n",
|
| 795 |
-
" download_urls(download_list,_link_instead_of_copy = _link_instead_of_copy, sync=sync, thread_num=thread_num or 3,is_await=is_await)\n",
|
| 796 |
-
" except:\n",
|
| 797 |
-
" pass"
|
| 798 |
-
]
|
| 799 |
-
},
|
| 800 |
-
{
|
| 801 |
-
"cell_type": "markdown",
|
| 802 |
-
"metadata": {
|
| 803 |
-
"id": "p0uS-BLULCtD"
|
| 804 |
-
},
|
| 805 |
-
"source": [
|
| 806 |
-
"## kaggle public API\n",
|
| 807 |
-
"\n",
|
| 808 |
-
"**不能使用%cd这种会改变当前工作目录的命令,会导致和其他线程冲突**\n",
|
| 809 |
-
"\n",
|
| 810 |
-
"---"
|
| 811 |
-
]
|
| 812 |
-
},
|
| 813 |
-
{
|
| 814 |
-
"cell_type": "code",
|
| 815 |
-
"execution_count": null,
|
| 816 |
-
"metadata": {
|
| 817 |
-
"_kg_hide-input": true,
|
| 818 |
-
"id": "m8FJi4j0LCtD",
|
| 819 |
-
"trusted": true
|
| 820 |
-
},
|
| 821 |
-
"outputs": [],
|
| 822 |
-
"source": [
|
| 823 |
-
"# 安装kaggle的api token文件\n",
|
| 824 |
-
"def initKaggleConfig():\n",
|
| 825 |
-
" if Path('~/.kaggle/kaggle.json').exists():\n",
|
| 826 |
-
" return True\n",
|
| 827 |
-
" if Path(kaggleApiTokenFile).exists():\n",
|
| 828 |
-
" run(f'''mkdir -p ~/.kaggle/''')\n",
|
| 829 |
-
" run('cp '+kaggleApiTokenFile+' ~/.kaggle/kaggle.json')\n",
|
| 830 |
-
" run(f'''chmod 600 ~/.kaggle/kaggle.json''')\n",
|
| 831 |
-
" return True\n",
|
| 832 |
-
" print('缺少kaggle的apiToken文件,访问:https://www.kaggle.com/你的kaggle用户名/account 获取')\n",
|
| 833 |
-
" return False\n",
|
| 834 |
-
"\n",
|
| 835 |
-
"def getUserName():\n",
|
| 836 |
-
" if not initKaggleConfig(): return\n",
|
| 837 |
-
" import kaggle\n",
|
| 838 |
-
" return kaggle.KaggleApi().read_config_file()['username']\n",
|
| 839 |
-
"\n",
|
| 840 |
-
"def createOrUpdateDataSet(path:str,datasetName:str):\n",
|
| 841 |
-
" if not initKaggleConfig(): return\n",
|
| 842 |
-
" print('创建或更新数据集 '+datasetName)\n",
|
| 843 |
-
" import kaggle\n",
|
| 844 |
-
" run(f'mkdir -p {_install_path}/kaggle_cache')\n",
|
| 845 |
-
" run(f'rm -rf {_install_path}/kaggle_cache/*')\n",
|
| 846 |
-
" datasetDirPath = _install_path+'/kaggle_cache/'+datasetName\n",
|
| 847 |
-
" run('mkdir -p '+datasetDirPath)\n",
|
| 848 |
-
" run('cp -f '+path+' '+datasetDirPath+'/')\n",
|
| 849 |
-
" username = getUserName()\n",
|
| 850 |
-
" print(\"kaggle username:\"+username)\n",
|
| 851 |
-
" datasetPath = username+'/'+datasetName\n",
|
| 852 |
-
" datasetList = kaggle.api.dataset_list(mine=True,search=datasetPath)\n",
|
| 853 |
-
" print(datasetList)\n",
|
| 854 |
-
" if len(datasetList) == 0 or datasetPath not in [str(d) for d in datasetList]: # 创建 create\n",
|
| 855 |
-
" run('kaggle datasets init -p' + datasetDirPath)\n",
|
| 856 |
-
" metadataFile = datasetDirPath+'/dataset-metadata.json'\n",
|
| 857 |
-
" run('sed -i s/INSERT_TITLE_HERE/'+ datasetName + '/g ' + metadataFile)\n",
|
| 858 |
-
" run('sed -i s/INSERT_SLUG_HERE/'+ datasetName + '/g ' + metadataFile)\n",
|
| 859 |
-
" run('cat '+metadataFile)\n",
|
| 860 |
-
" run('kaggle datasets create -p '+datasetDirPath)\n",
|
| 861 |
-
" print('create database done')\n",
|
| 862 |
-
" else:\n",
|
| 863 |
-
" kaggle.api.dataset_metadata(datasetPath,datasetDirPath)\n",
|
| 864 |
-
" kaggle.api.dataset_create_version(datasetDirPath, 'auto update',dir_mode='zip')\n",
|
| 865 |
-
" print('upload database done')\n",
|
| 866 |
-
"\n",
|
| 867 |
-
"def downloadDatasetFiles(datasetName:str,outputPath:str):\n",
|
| 868 |
-
" if not initKaggleConfig(): return\n",
|
| 869 |
-
" print('下载数据集文件 '+datasetName)\n",
|
| 870 |
-
" import kaggle\n",
|
| 871 |
-
" username = getUserName()\n",
|
| 872 |
-
" datasetPath = username+'/'+datasetName\n",
|
| 873 |
-
" datasetList = kaggle.api.dataset_list(mine=True,search=datasetPath)\n",
|
| 874 |
-
" if datasetPath not in [str(d) for d in datasetList]:\n",
|
| 875 |
-
" return False\n",
|
| 876 |
-
" run('mkdir -p '+outputPath)\n",
|
| 877 |
-
" kaggle.api.dataset_download_files(datasetPath,path=outputPath,unzip=True)\n",
|
| 878 |
-
" return True\n",
|
| 879 |
-
"\n"
|
| 880 |
-
]
|
| 881 |
-
},
|
| 882 |
-
{
|
| 883 |
-
"cell_type": "markdown",
|
| 884 |
-
"metadata": {},
|
| 885 |
-
"source": [
|
| 886 |
-
"## 同步文件夹到 huggingface\n",
|
| 887 |
-
"\n",
|
| 888 |
-
"---"
|
| 889 |
-
]
|
| 890 |
-
},
|
| 891 |
-
{
|
| 892 |
-
"cell_type": "code",
|
| 893 |
-
"execution_count": null,
|
| 894 |
-
"metadata": {
|
| 895 |
-
"trusted": true
|
| 896 |
-
},
|
| 897 |
-
"outputs": [],
|
| 898 |
-
"source": [
|
| 899 |
-
"# 文件夹与 huggingface 同步\n",
|
| 900 |
-
"if _huggingface_token and _huggingface_repo:\n",
|
| 901 |
-
" if not is_installed('watchdog'):\n",
|
| 902 |
-
" requirements.append('watchdog')\n",
|
| 903 |
-
" if not is_installed('huggingface_hub'):\n",
|
| 904 |
-
" requirements.append('huggingface_hub')\n",
|
| 905 |
-
" else:\n",
|
| 906 |
-
" try:\n",
|
| 907 |
-
" from huggingface_hub import HfApi,login,snapshot_download\n",
|
| 908 |
-
" except:\n",
|
| 909 |
-
" requirements.append('huggingface_hub')\n",
|
| 910 |
-
"\n",
|
| 911 |
-
"huggingface_is_init = False\n",
|
| 912 |
-
"\n",
|
| 913 |
-
"def init_huggingface():\n",
|
| 914 |
-
" if not _huggingface_token:\n",
|
| 915 |
-
" return False\n",
|
| 916 |
-
"\n",
|
| 917 |
-
" global huggingface_headers\n",
|
| 918 |
-
" global huggingface_is_init\n",
|
| 919 |
-
" \n",
|
| 920 |
-
" from huggingface_hub import login\n",
|
| 921 |
-
" token = replace_path(_huggingface_token)\n",
|
| 922 |
-
" if not _huggingface_token.startswith('hf_') and Path(token).exists():\n",
|
| 923 |
-
" with open(token,encoding = \"utf-8\") as nkfile:\n",
|
| 924 |
-
" token = nkfile.readline()\n",
|
| 925 |
-
" if not token.startswith('hf_'):\n",
|
| 926 |
-
" print('huggingface token 不正确,请将 token 或 仅存放token 的txt文件路径填入 _huggingface_token 配置')\n",
|
| 927 |
-
" return False\n",
|
| 928 |
-
" login(token,add_to_git_credential=True)\n",
|
| 929 |
-
" huggingface_headers = {'Authorization': 'Bearer '+token}\n",
|
| 930 |
-
" print('huggingface token 已经加载,可以下载私有仓库或文件')\n",
|
| 931 |
-
" \n",
|
| 932 |
-
" if not _huggingface_repo:\n",
|
| 933 |
-
" print('huggingface 同步收藏图片功能不会启动,可增加配置项 huggingface_token = \"token\" 和 huggingface_repo = “仓库id” 后启用 huggingface 同步收藏图片功能')\n",
|
| 934 |
-
" return False\n",
|
| 935 |
-
" huggingface_is_init = True\n",
|
| 936 |
-
" return True\n",
|
| 937 |
-
"\n",
|
| 938 |
-
"\n",
|
| 939 |
-
"def download__huggingface_repo(repo_id:str,dist_directory:str=None,repo_type='dataset',callback=None):\n",
|
| 940 |
-
" if not huggingface_is_init:\n",
|
| 941 |
-
" print('huggingface 相关功能未初始化 请调用 init_huggingface() 初始化')\n",
|
| 942 |
-
" \n",
|
| 943 |
-
" if not dist_directory:\n",
|
| 944 |
-
" dist_directory = f'{_install_path}/{_ui_dir_name}/log'\n",
|
| 945 |
-
" \n",
|
| 946 |
-
" print('下载收藏的图片')\n",
|
| 947 |
-
" if not Path(f'{_install_path}/cache/huggingface/huggingface_repo').exists():\n",
|
| 948 |
-
" mkdirs(f'{_install_path}/cache/huggingface')\n",
|
| 949 |
-
" repo_path = ''\n",
|
| 950 |
-
" if repo_type == 'dataset':\n",
|
| 951 |
-
" repo_path = 'datasets'\n",
|
| 952 |
-
" if repo_type == 'space':\n",
|
| 953 |
-
" repo_path = 'spaces'\n",
|
| 954 |
-
" if repo_path:\n",
|
| 955 |
-
" run(f'git clone https://huggingface.co/{repo_path}/{repo_id} huggingface_repo',cwd=f'{_install_path}/cache/huggingface')\n",
|
| 956 |
-
" else:\n",
|
| 957 |
-
" run(f'git clone https://huggingface.co/{repo_id} huggingface_repo',cwd=f'{_install_path}/cache/huggingface')\n",
|
| 958 |
-
" if Path(f'{_install_path}/cache/huggingface/huggingface_repo').exists():\n",
|
| 959 |
-
" run(f'cp -r -f -n -s {_install_path}/cache/huggingface/huggingface_repo/* {dist_directory}')\n",
|
| 960 |
-
" if callback:\n",
|
| 961 |
-
" callback()\n",
|
| 962 |
-
"\n",
|
| 963 |
-
"def start_sync_log_to_huggingface(repo_id:str,directory_to_watch:str=None,repo_type='dataset'):\n",
|
| 964 |
-
" if not huggingface_is_init:\n",
|
| 965 |
-
" print('huggingface 相关功能未初始化 请调用 init_huggingface() 初始化')\n",
|
| 966 |
-
" \n",
|
| 967 |
-
" from watchdog.observers import Observer\n",
|
| 968 |
-
" from watchdog.events import FileSystemEventHandler\n",
|
| 969 |
-
" from huggingface_hub import HfApi,login,snapshot_download\n",
|
| 970 |
-
" \n",
|
| 971 |
-
" # 配置监视的目录和 Hugging Face 仓库信息\n",
|
| 972 |
-
" class FileChangeHandler(FileSystemEventHandler):\n",
|
| 973 |
-
" def __init__(self, api, repo_id, repo_type,directory_to_watch):\n",
|
| 974 |
-
" self.api = api\n",
|
| 975 |
-
" self.repo_id = repo_id\n",
|
| 976 |
-
" self.repo_type = repo_type\n",
|
| 977 |
-
" self.directory_to_watch = directory_to_watch\n",
|
| 978 |
-
" def on_created(self, event):\n",
|
| 979 |
-
" if not event.is_directory:\n",
|
| 980 |
-
" # 上传新文件到 Hugging Face 仓库\n",
|
| 981 |
-
" file_path = event.src_path\n",
|
| 982 |
-
" file_name:str = os.path.basename(file_path)\n",
|
| 983 |
-
" print(file_name)\n",
|
| 984 |
-
" if file_name[file_name.rindex('.'):] not in ['.png','.jpg','.txt','.webp','.jpeg']: return\n",
|
| 985 |
-
" print(file_name,'>>','huggingface')\n",
|
| 986 |
-
" try:\n",
|
| 987 |
-
" self.api.upload_file(\n",
|
| 988 |
-
" path_or_fileobj=file_path,\n",
|
| 989 |
-
" path_in_repo=file_path.replace(self.directory_to_watch,''),\n",
|
| 990 |
-
" repo_id=self.repo_id,\n",
|
| 991 |
-
" repo_type=self.repo_type,\n",
|
| 992 |
-
" )\n",
|
| 993 |
-
" except IOError as error:\n",
|
| 994 |
-
" print(error)\n",
|
| 995 |
-
"\n",
|
| 996 |
-
" def on_deleted(self, event):\n",
|
| 997 |
-
" if not event.is_directory:\n",
|
| 998 |
-
" # 从 Hugging Face 仓库删除文件\n",
|
| 999 |
-
" file_path = event.src_path\n",
|
| 1000 |
-
" file_name = os.path.basename(file_path)\n",
|
| 1001 |
-
" if file_name[file_name.rindex('.'):] not in ['.png','.jpg','.txt','.webp','.jpeg']: return\n",
|
| 1002 |
-
" try:\n",
|
| 1003 |
-
" self.api.delete_file(\n",
|
| 1004 |
-
" path_in_repo=file_path.replace(self.directory_to_watch,''),\n",
|
| 1005 |
-
" repo_id=self.repo_id,\n",
|
| 1006 |
-
" repo_type=self.repo_type,\n",
|
| 1007 |
-
" )\n",
|
| 1008 |
-
" except IOError as error:\n",
|
| 1009 |
-
" print(error)\n",
|
| 1010 |
-
"\n",
|
| 1011 |
-
" def on_modified(self, event):\n",
|
| 1012 |
-
" if not event.is_directory:\n",
|
| 1013 |
-
" # 更新 Hugging Face 仓库中的文件\n",
|
| 1014 |
-
" file_path = event.src_path\n",
|
| 1015 |
-
" file_name = os.path.basename(file_path)\n",
|
| 1016 |
-
" if file_name[file_name.rindex('.'):] not in ['.png','.jpg','.txt','.webp','.jpeg']: return\n",
|
| 1017 |
-
" try:\n",
|
| 1018 |
-
" self.api.upload_file(\n",
|
| 1019 |
-
" path_or_fileobj=file_path,\n",
|
| 1020 |
-
" path_in_repo=file_path.replace(self.directory_to_watch,''),\n",
|
| 1021 |
-
" repo_id=self.repo_id,\n",
|
| 1022 |
-
" repo_type=self.repo_type,\n",
|
| 1023 |
-
" )\n",
|
| 1024 |
-
" except IOError as error:\n",
|
| 1025 |
-
" print(error)\n",
|
| 1026 |
-
"\n",
|
| 1027 |
-
" def on_moved(self, event):\n",
|
| 1028 |
-
" if not event.is_directory:\n",
|
| 1029 |
-
" file_path = event.dest_path\n",
|
| 1030 |
-
" file_name = os.path.basename(file_path)\n",
|
| 1031 |
-
" if file_name[file_name.rindex('.'):] not in ['.png','.jpg','.txt','.webp','.jpeg']: return\n",
|
| 1032 |
-
" if event.dest_path.startswith(self.directory_to_watch):\n",
|
| 1033 |
-
" try:\n",
|
| 1034 |
-
" self.api.upload_file(\n",
|
| 1035 |
-
" path_or_fileobj=file_path,\n",
|
| 1036 |
-
" path_in_repo=file_path.replace(self.directory_to_watch,''),\n",
|
| 1037 |
-
" repo_id=self.repo_id,\n",
|
| 1038 |
-
" repo_type=self.repo_type,\n",
|
| 1039 |
-
" )\n",
|
| 1040 |
-
" except IOError as error:\n",
|
| 1041 |
-
" print(error)\n",
|
| 1042 |
-
"\n",
|
| 1043 |
-
" api = HfApi()\n",
|
| 1044 |
-
" \n",
|
| 1045 |
-
" if not directory_to_watch:\n",
|
| 1046 |
-
" directory_to_watch = f'{_install_path}/{_ui_dir_name}/log'\n",
|
| 1047 |
-
" # 创建观察者对象并注册文件变化处理程序\n",
|
| 1048 |
-
" event_handler = FileChangeHandler(api,repo_id,repo_type,directory_to_watch)\n",
|
| 1049 |
-
" observer = Observer()\n",
|
| 1050 |
-
" observer.schedule(event_handler, directory_to_watch, recursive=True)\n",
|
| 1051 |
-
"\n",
|
| 1052 |
-
" # 启动观察者\n",
|
| 1053 |
-
" observer.name = \"solo_directory_to_watch\"\n",
|
| 1054 |
-
" print(f'启动收藏图片文件夹监听,并自动同步到 huggingface {repo_type} : {repo_id}')\n",
|
| 1055 |
-
" observer.start()"
|
| 1056 |
-
]
|
| 1057 |
-
},
|
| 1058 |
-
{
|
| 1059 |
-
"cell_type": "markdown",
|
| 1060 |
-
"metadata": {
|
| 1061 |
-
"id": "sswa04veLCtE"
|
| 1062 |
-
},
|
| 1063 |
-
"source": [
|
| 1064 |
-
"## 工具函数\n",
|
| 1065 |
-
"**不能使用%cd这种会改变当前工作目录的命令,会导致和其他线程冲突**\n",
|
| 1066 |
-
"\n",
|
| 1067 |
-
"---"
|
| 1068 |
-
]
|
| 1069 |
-
},
|
| 1070 |
-
{
|
| 1071 |
-
"cell_type": "code",
|
| 1072 |
-
"execution_count": null,
|
| 1073 |
-
"metadata": {
|
| 1074 |
-
"_kg_hide-input": true,
|
| 1075 |
-
"trusted": true
|
| 1076 |
-
},
|
| 1077 |
-
"outputs": [],
|
| 1078 |
-
"source": [
|
| 1079 |
-
"\n",
|
| 1080 |
-
"def zipPath(path:str,zipName:str,format='tar'):\n",
|
| 1081 |
-
" if path.startswith('$install_path'):\n",
|
| 1082 |
-
" path = path.replace('$install_path',_install_path)\n",
|
| 1083 |
-
" if path.startswith('$output_path'):\n",
|
| 1084 |
-
" path = path.replace('$install_path',_output_path)\n",
|
| 1085 |
-
" if not path.startswith('/'):\n",
|
| 1086 |
-
" path = f'{_install_path}/{_ui_dir_name}/{path}'\n",
|
| 1087 |
-
" if Path(path).exists():\n",
|
| 1088 |
-
" if 'tar' == format:\n",
|
| 1089 |
-
" run(f'tar -cf {_output_path}/'+ zipName +'.tar -C '+ path +' . ')\n",
|
| 1090 |
-
" elif 'gz' == format:\n",
|
| 1091 |
-
" run(f'tar -czf {_output_path}/'+ zipName +'.tar.gz -C '+ path +' . ')\n",
|
| 1092 |
-
" return\n",
|
| 1093 |
-
" print('指定的目录不存在:'+path)\n",
|
| 1094 |
-
" \n",
|
| 1095 |
-
"def get_folder_list(directory:str): \n",
|
| 1096 |
-
" folder_list = [] \n",
|
| 1097 |
-
" for item in os.listdir(directory): \n",
|
| 1098 |
-
" if os.path.isdir(os.path.join(directory, item)): \n",
|
| 1099 |
-
" folder_list.append(item) \n",
|
| 1100 |
-
" return folder_list\n",
|
| 1101 |
-
"\n",
|
| 1102 |
-
"def read_text_file(file_path:str):\n",
|
| 1103 |
-
" if not Path(file_path).exists(): return ''\n",
|
| 1104 |
-
" with open(file_path,\"r\") as f:\n",
|
| 1105 |
-
" text = file.read()\n",
|
| 1106 |
-
" if text: return text.strip()\n",
|
| 1107 |
-
" return ''"
|
| 1108 |
-
]
|
| 1109 |
-
},
|
| 1110 |
-
{
|
| 1111 |
-
"cell_type": "markdown",
|
| 1112 |
-
"metadata": {},
|
| 1113 |
-
"source": [
|
| 1114 |
-
"## 内网穿透\n",
|
| 1115 |
-
"\n",
|
| 1116 |
-
"---"
|
| 1117 |
-
]
|
| 1118 |
-
},
|
| 1119 |
-
{
|
| 1120 |
-
"cell_type": "code",
|
| 1121 |
-
"execution_count": null,
|
| 1122 |
-
"metadata": {
|
| 1123 |
-
"_kg_hide-input": true,
|
| 1124 |
-
"_kg_hide-output": true,
|
| 1125 |
-
"id": "coqQvTSLLCtE",
|
| 1126 |
-
"trusted": true
|
| 1127 |
-
},
|
| 1128 |
-
"outputs": [],
|
| 1129 |
-
"source": [
|
| 1130 |
-
"def printUrl(url,name=''):\n",
|
| 1131 |
-
" print(f'{name} 访问地址:{url}')\n",
|
| 1132 |
-
" for key in sorted(_proxy_path.keys(), key=len)[::-1]:\n",
|
| 1133 |
-
" print(f'{name} 本地服务:{_proxy_path[key]} 访问地址:{url}{key}')\n",
|
| 1134 |
-
"# ngrok\n",
|
| 1135 |
-
"def startNgrok(ngrokToken:str,ngrokLocalPort:int):\n",
|
| 1136 |
-
" if not is_installed('pyngrok'):\n",
|
| 1137 |
-
" run('pip install pyngrok')\n",
|
| 1138 |
-
" from pyngrok import conf, ngrok\n",
|
| 1139 |
-
" try:\n",
|
| 1140 |
-
" conf.get_default().auth_token = ngrokToken\n",
|
| 1141 |
-
" conf.get_default().monitor_thread = False\n",
|
| 1142 |
-
" ssh_tunnels = ngrok.get_tunnels(conf.get_default())\n",
|
| 1143 |
-
" url = ''\n",
|
| 1144 |
-
" if len(ssh_tunnels) == 0:\n",
|
| 1145 |
-
" ssh_tunnel = ngrok.connect(ngrokLocalPort)\n",
|
| 1146 |
-
" url = ssh_tunnel.public_url\n",
|
| 1147 |
-
" print('ngrok 访问地址:'+ssh_tunnel.public_url)\n",
|
| 1148 |
-
" else:\n",
|
| 1149 |
-
" print('ngrok 访问地址:'+ssh_tunnels[0].public_url)\n",
|
| 1150 |
-
" url = ssh_tunnels[0].public_url\n",
|
| 1151 |
-
" printUrl(url,'ngrok')\n",
|
| 1152 |
-
" def auto_request_ngrok():\n",
|
| 1153 |
-
" if url:\n",
|
| 1154 |
-
" while(_runing):\n",
|
| 1155 |
-
" time.sleep(60*1)\n",
|
| 1156 |
-
" try:\n",
|
| 1157 |
-
" res = requests.get(url+'/',headers={\"ngrok-skip-browser-warning\" : \"1\"},timeout=10)\n",
|
| 1158 |
-
" except:\n",
|
| 1159 |
-
" ''\n",
|
| 1160 |
-
" # print('自动调用ngrok链接以保存链接不会断开',res.status_code)\n",
|
| 1161 |
-
"\n",
|
| 1162 |
-
" # threading.Thread(target = auto_request_ngrok,daemon=True,name='solo_auto_request_ngrok').start()\n",
|
| 1163 |
-
" except:\n",
|
| 1164 |
-
" print('启动ngrok出错')\n",
|
| 1165 |
-
" \n",
|
| 1166 |
-
"def startFrpc(name,configFile):\n",
|
| 1167 |
-
" if not Path(f'{_install_path}/frpc/frpc').exists():\n",
|
| 1168 |
-
" installFrpExe()\n",
|
| 1169 |
-
" if freefrp_url:\n",
|
| 1170 |
-
" printUrl(freefrp_url,'freefrp')\n",
|
| 1171 |
-
" echoToFile(f'''\n",
|
| 1172 |
-
"cd {_install_path}/frpc/\n",
|
| 1173 |
-
"{_install_path}/frpc/frpc {configFile}\n",
|
| 1174 |
-
"''',f'{_install_path}/frpc/start.sh')\n",
|
| 1175 |
-
" get_ipython().system(f'''bash {_install_path}/frpc/start.sh''')\n",
|
| 1176 |
-
" \n",
|
| 1177 |
-
"def installFrpExe():\n",
|
| 1178 |
-
" if _useFrpc:\n",
|
| 1179 |
-
" print('安装frpc')\n",
|
| 1180 |
-
" run(f'mkdir -p {_install_path}/frpc')\n",
|
| 1181 |
-
" if Path(frpcExePath).exists():\n",
|
| 1182 |
-
" run(f'cp -f -n {frpcExePath} {_install_path}/frpc/frpc')\n",
|
| 1183 |
-
" else:\n",
|
| 1184 |
-
" run(f'wget \"https://huggingface.co/datasets/ACCA225/Frp/resolve/main/frpc\" -O {_install_path}/frpc/frpc')\n",
|
| 1185 |
-
" \n",
|
| 1186 |
-
" for ssl in frpcSSLFFlies:\n",
|
| 1187 |
-
" if Path(ssl).exists():\n",
|
| 1188 |
-
" run(f'cp -f -n {ssl}/* {_install_path}/frpc/')\n",
|
| 1189 |
-
" run(f'chmod +x {_install_path}/frpc/frpc')\n",
|
| 1190 |
-
" run(f'{_install_path}/frpc/frpc -v')\n",
|
| 1191 |
-
"\n",
|
| 1192 |
-
"def startProxy():\n",
|
| 1193 |
-
" if _useNgrok:\n",
|
| 1194 |
-
" startNgrok(ngrokToken,_server_port)\n",
|
| 1195 |
-
" if _useFrpc:\n",
|
| 1196 |
-
" startFrpc('frpc_proxy',frpcStartArg)"
|
| 1197 |
-
]
|
| 1198 |
-
},
|
| 1199 |
-
{
|
| 1200 |
-
"cell_type": "markdown",
|
| 1201 |
-
"metadata": {},
|
| 1202 |
-
"source": [
|
| 1203 |
-
"## NGINX 反向代理\n",
|
| 1204 |
-
"\n",
|
| 1205 |
-
"---"
|
| 1206 |
-
]
|
| 1207 |
-
},
|
| 1208 |
-
{
|
| 1209 |
-
"cell_type": "code",
|
| 1210 |
-
"execution_count": null,
|
| 1211 |
-
"metadata": {
|
| 1212 |
-
"_kg_hide-input": true,
|
| 1213 |
-
"_kg_hide-output": true,
|
| 1214 |
-
"trusted": true
|
| 1215 |
-
},
|
| 1216 |
-
"outputs": [],
|
| 1217 |
-
"source": [
|
| 1218 |
-
"\n",
|
| 1219 |
-
"# nginx 反向代理配置文件\n",
|
| 1220 |
-
"def localProxy():\n",
|
| 1221 |
-
" def getProxyLocation(subPath:str, localServer:str):\n",
|
| 1222 |
-
" return '''\n",
|
| 1223 |
-
" location '''+ subPath +'''\n",
|
| 1224 |
-
" {\n",
|
| 1225 |
-
" proxy_pass '''+ localServer +''';\n",
|
| 1226 |
-
" \n",
|
| 1227 |
-
" client_max_body_size 1000m;\n",
|
| 1228 |
-
" proxy_set_header Host $http_host;\n",
|
| 1229 |
-
" proxy_set_header X-Real-IP $remote_addr;\n",
|
| 1230 |
-
" proxy_set_header X-Real-Port $remote_port;\n",
|
| 1231 |
-
" proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n",
|
| 1232 |
-
" proxy_set_header X-Forwarded-Proto $scheme;\n",
|
| 1233 |
-
" proxy_set_header X-Forwarded-Host $host;\n",
|
| 1234 |
-
" proxy_set_header X-Forwarded-Port $server_port;\n",
|
| 1235 |
-
" proxy_set_header REMOTE-HOST $remote_addr;\n",
|
| 1236 |
-
" proxy_connect_timeout 3000s;\n",
|
| 1237 |
-
" proxy_send_timeout 3000s;\n",
|
| 1238 |
-
" proxy_read_timeout 3000s;\n",
|
| 1239 |
-
" proxy_http_version 1.1;\n",
|
| 1240 |
-
" proxy_set_header Upgrade $http_upgrade;\n",
|
| 1241 |
-
" proxy_set_header Connection 'upgrade';\n",
|
| 1242 |
-
" add_header Access-Control-Allow-Origin * always;\n",
|
| 1243 |
-
" add_header Access-Control-Allow-Headers *;\n",
|
| 1244 |
-
" add_header Access-Control-Allow-Methods \"GET, POST, PUT, OPTIONS\";\n",
|
| 1245 |
-
" }\n",
|
| 1246 |
-
" \n",
|
| 1247 |
-
" '''\n",
|
| 1248 |
-
" \n",
|
| 1249 |
-
" conf = '''\n",
|
| 1250 |
-
"server\n",
|
| 1251 |
-
"{\n",
|
| 1252 |
-
" listen '''+str(_server_port)+''';\n",
|
| 1253 |
-
" listen [::]:'''+str(_server_port)+''';\n",
|
| 1254 |
-
" server_name 127.0.0.1 localhost 0.0.0.0 \"\";\n",
|
| 1255 |
-
" \n",
|
| 1256 |
-
" fastcgi_send_timeout 3000s;\n",
|
| 1257 |
-
" fastcgi_read_timeout 3000s;\n",
|
| 1258 |
-
" fastcgi_connect_timeout 3000s;\n",
|
| 1259 |
-
" \n",
|
| 1260 |
-
" if ($request_method = OPTIONS) {\n",
|
| 1261 |
-
" return 200;\n",
|
| 1262 |
-
" }\n",
|
| 1263 |
-
" \n",
|
| 1264 |
-
" '''+ ''.join([getProxyLocation(key,_proxy_path[key]) for key in sorted(_proxy_path.keys(), key=len)[::-1]]) +'''\n",
|
| 1265 |
-
"}\n",
|
| 1266 |
-
"'''\n",
|
| 1267 |
-
" echoToFile(conf,'/etc/nginx/conf.d/proxy_nginx.conf')\n",
|
| 1268 |
-
" if not check_service('localhost',_server_port):\n",
|
| 1269 |
-
" run(f'''nginx -c /etc/nginx/nginx.conf''')\n",
|
| 1270 |
-
" run(f'''nginx -s reload''')"
|
| 1271 |
-
]
|
| 1272 |
-
},
|
| 1273 |
-
{
|
| 1274 |
-
"cell_type": "markdown",
|
| 1275 |
-
"metadata": {},
|
| 1276 |
-
"source": [
|
| 1277 |
-
"## 线程清理工具\n",
|
| 1278 |
-
"\n",
|
| 1279 |
-
"---\n",
|
| 1280 |
-
"\n",
|
| 1281 |
-
"清理线程名以 solo_ 开头的所有线程"
|
| 1282 |
-
]
|
| 1283 |
-
},
|
| 1284 |
-
{
|
| 1285 |
-
"cell_type": "code",
|
| 1286 |
-
"execution_count": null,
|
| 1287 |
-
"metadata": {
|
| 1288 |
-
"_kg_hide-input": true,
|
| 1289 |
-
"trusted": true
|
| 1290 |
-
},
|
| 1291 |
-
"outputs": [],
|
| 1292 |
-
"source": [
|
| 1293 |
-
"import inspect\n",
|
| 1294 |
-
"import ctypes\n",
|
| 1295 |
-
"\n",
|
| 1296 |
-
"def _async_raise(tid, exctype):\n",
|
| 1297 |
-
" \"\"\"raises the exception, performs cleanup if needed\"\"\"\n",
|
| 1298 |
-
" tid = ctypes.c_long(tid)\n",
|
| 1299 |
-
" if not inspect.isclass(exctype):\n",
|
| 1300 |
-
" exctype = type(exctype)\n",
|
| 1301 |
-
" res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))\n",
|
| 1302 |
-
" if res == 0:\n",
|
| 1303 |
-
" raise ValueError(\"invalid thread id\")\n",
|
| 1304 |
-
" elif res != 1:\n",
|
| 1305 |
-
" # \"\"\"if it returns a number greater than one, you're in trouble,\n",
|
| 1306 |
-
" # and you should call it again with exc=NULL to revert the effect\"\"\"\n",
|
| 1307 |
-
" ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)\n",
|
| 1308 |
-
" raise SystemError(\"PyThreadState_SetAsyncExc failed\")\n",
|
| 1309 |
-
"\n",
|
| 1310 |
-
"def stop_thread(thread):\n",
|
| 1311 |
-
" _async_raise(thread.ident, SystemExit)\n",
|
| 1312 |
-
"\n",
|
| 1313 |
-
"def stop_solo_threads():\n",
|
| 1314 |
-
" global _runing\n",
|
| 1315 |
-
" _runing = False\n",
|
| 1316 |
-
" # 获取当前所有活动的线程\n",
|
| 1317 |
-
" threads = threading.enumerate()\n",
|
| 1318 |
-
" # 关闭之前创建的子线程\n",
|
| 1319 |
-
" for thread in threads:\n",
|
| 1320 |
-
" if thread.name.startswith('solo_'):\n",
|
| 1321 |
-
" print(f'结束线程:{thread.name}')\n",
|
| 1322 |
-
" try:\n",
|
| 1323 |
-
" stop_thread(thread)\n",
|
| 1324 |
-
" except socket.error:\n",
|
| 1325 |
-
" print(f'结束线程:{thread.name} 执行失败')"
|
| 1326 |
-
]
|
| 1327 |
-
},
|
| 1328 |
-
{
|
| 1329 |
-
"cell_type": "markdown",
|
| 1330 |
-
"metadata": {
|
| 1331 |
-
"id": "Ve3p8oOkLCtE"
|
| 1332 |
-
},
|
| 1333 |
-
"source": [
|
| 1334 |
-
"# webui 安装和配置函数\n",
|
| 1335 |
-
"---"
|
| 1336 |
-
]
|
| 1337 |
-
},
|
| 1338 |
-
{
|
| 1339 |
-
"cell_type": "code",
|
| 1340 |
-
"execution_count": null,
|
| 1341 |
-
"metadata": {
|
| 1342 |
-
"_kg_hide-input": true,
|
| 1343 |
-
"id": "GTjyBJihLCtE",
|
| 1344 |
-
"trusted": true
|
| 1345 |
-
},
|
| 1346 |
-
"outputs": [],
|
| 1347 |
-
"source": [
|
| 1348 |
-
"envInstalled=False\n",
|
| 1349 |
-
"quickStart = False\n",
|
| 1350 |
-
"#安装\n",
|
| 1351 |
-
"def install():\n",
|
| 1352 |
-
" print('安装')\n",
|
| 1353 |
-
" os.chdir(f'''{_install_path}''')\n",
|
| 1354 |
-
" run(f'''git lfs install''')\n",
|
| 1355 |
-
" run(f'''git config --global credential.helper store''')\n",
|
| 1356 |
-
" for requirement in requirements:\n",
|
| 1357 |
-
" run(f'pip install {requirement}')\n",
|
| 1358 |
-
" if _reLoad:\n",
|
| 1359 |
-
" run(f'''rm -rf {_install_path}/{_ui_dir_name}''')\n",
|
| 1360 |
-
" if Path(f\"{_ui_dir_name}\").exists():\n",
|
| 1361 |
-
" os.chdir(f'''{_install_path}/{_ui_dir_name}/''')\n",
|
| 1362 |
-
" run(f'''git checkout .''')\n",
|
| 1363 |
-
" run(f'''git pull''')\n",
|
| 1364 |
-
" else:\n",
|
| 1365 |
-
" run(f'''git clone --recursive {_sd_git_repo} {_ui_dir_name}''')\n",
|
| 1366 |
-
" if not Path(f'''{_install_path}/{_ui_dir_name}''').exists():\n",
|
| 1367 |
-
" print('sd-webui主程序安装失败,请检查 sd_git_repo 配置的值是否正确')\n",
|
| 1368 |
-
" sys.exit(0)\n",
|
| 1369 |
-
" os.chdir(f'''{_install_path}/{_ui_dir_name}''')\n",
|
| 1370 |
-
" print('安装 完成')\n",
|
| 1371 |
-
"\n",
|
| 1372 |
-
"# 链接输出目录\n",
|
| 1373 |
-
"def link_dir():\n",
|
| 1374 |
-
" print('链接输出目录')\n",
|
| 1375 |
-
" # 链接图片输出目录\n",
|
| 1376 |
-
" run(f'''mkdir -p {_output_path}/outputs''')\n",
|
| 1377 |
-
" run(f'''rm -rf {_install_path}/{_ui_dir_name}/outputs''')\n",
|
| 1378 |
-
" run(f'''ln -s -r {_output_path}/outputs {_install_path}/{_ui_dir_name}/''')\n",
|
| 1379 |
-
" # 输出收藏目录\n",
|
| 1380 |
-
" run(f'''mkdir -p {_output_path}/log''')\n",
|
| 1381 |
-
" run(f'''rm -rf {_install_path}/{_ui_dir_name}/log''')\n",
|
| 1382 |
-
" run(f'''ln -s -r {_output_path}/log {_install_path}/{_ui_dir_name}/''')\n",
|
| 1383 |
-
" # 链接训练输出目录 文件夹链接会导致功能不能用\n",
|
| 1384 |
-
" run(f'''rm -rf {_install_path}/{_ui_dir_name}/textual_inversion''')\n",
|
| 1385 |
-
" run(f'''mkdir -p {_output_path}/textual_inversion/''')\n",
|
| 1386 |
-
" run(f'''ln -s -r {_output_path}/textual_inversion {_install_path}/{_ui_dir_name}/''')\n",
|
| 1387 |
-
" print('链接输出目录 完成') \n",
|
| 1388 |
-
"\n",
|
| 1389 |
-
"def install_optimizing():\n",
|
| 1390 |
-
" run('add-apt-repository ppa:deadsnakes/ppa -y')\n",
|
| 1391 |
-
" run('apt update -y')\n",
|
| 1392 |
-
" run('apt install nginx -y')\n",
|
| 1393 |
-
" # run('apt install python3.10 -y')\n",
|
| 1394 |
-
" \n",
|
| 1395 |
-
"#安装依赖\n",
|
| 1396 |
-
"def install_dependencies():\n",
|
| 1397 |
-
" print('安装需要的python环境')\n",
|
| 1398 |
-
" global envInstalled\n",
|
| 1399 |
-
" global venvPath\n",
|
| 1400 |
-
" if Path(f'{_install_path}/{_ui_dir_name}/venv').exists():\n",
|
| 1401 |
-
" print('跳过安装python环境')\n",
|
| 1402 |
-
" envInstalled = True\n",
|
| 1403 |
-
" return\n",
|
| 1404 |
-
" \n",
|
| 1405 |
-
" if quickStart:\n",
|
| 1406 |
-
" if not Path(venvPath).exists():\n",
|
| 1407 |
-
" mkdirs(f'{_install_path}/venv_cache',True)\n",
|
| 1408 |
-
" if not Path(f'{_install_path}/venv_cache/venv.tar.bak').exists():\n",
|
| 1409 |
-
" print('下载 venv.zip')\n",
|
| 1410 |
-
" download_file('https://huggingface.co/viyi/sdwui/resolve/main/venv.zip','venv.zip',f'{_install_path}/venv_cache')\n",
|
| 1411 |
-
" run(f'''unzip {_install_path}/venv_cache/venv.zip -d {_install_path}/venv_cache''')\n",
|
| 1412 |
-
" venvPath = f'{_install_path}/venv_cache/venv.tar.bak'\n",
|
| 1413 |
-
" run(f'''rm -rf {_install_path}/venv_cache/venv.zip''')\n",
|
| 1414 |
-
" elif venvPath.endswith('.zip'):\n",
|
| 1415 |
-
" mkdirs(f'{_install_path}/venv_cache',True)\n",
|
| 1416 |
-
" run(f'''unzip {venvPath} -d {_install_path}/venv_cache''')\n",
|
| 1417 |
-
" venvPath = f'{_install_path}/venv_cache/venv.tar.bak'\n",
|
| 1418 |
-
" print('解压环境')\n",
|
| 1419 |
-
" mkdirs(f'{_install_path}/{_ui_dir_name}/venv')\n",
|
| 1420 |
-
"# run('python3.10 -m venv venv',cwd=f'{_install_path}/{_ui_dir_name}')\n",
|
| 1421 |
-
" run(f'tar -xf {venvPath} -C ./venv',cwd=f'{_install_path}/{_ui_dir_name}')\n",
|
| 1422 |
-
" run(f'rm -f {_install_path}/{_ui_dir_name}/venv/bin/pip*')\n",
|
| 1423 |
-
" run(f'rm -f {_install_path}/{_ui_dir_name}/venv/bin/python*')\n",
|
| 1424 |
-
" venv.create(f'{_install_path}/{_ui_dir_name}/venv')\n",
|
| 1425 |
-
" if not Path(f'{_install_path}/{_ui_dir_name}/venv/bin/pip').exists():\n",
|
| 1426 |
-
" run('curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py')\n",
|
| 1427 |
-
" run(f'{_install_path}/{_ui_dir_name}/venv/bin/python3 get-pip.py')\n",
|
| 1428 |
-
"\n",
|
| 1429 |
-
" get_ipython().system(f'''{_install_path}/{_ui_dir_name}/venv/bin/python3 -V''')\n",
|
| 1430 |
-
" get_ipython().system(f'''{_install_path}/{_ui_dir_name}/venv/bin/python3 -m pip -V''')\n",
|
| 1431 |
-
" \n",
|
| 1432 |
-
" if not quickStart:\n",
|
| 1433 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python3 -V''')\n",
|
| 1434 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python3 -m pip -V''')\n",
|
| 1435 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python -m pip install torch==2.3.1 torchvision==0.18.1 torchaudio==2.3.1 --index-url https://download.pytorch.org/whl/cu121''')\n",
|
| 1436 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python -m pip install xformers==0.0.27''')\n",
|
| 1437 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python -m pip install -r requirements_versions.txt''')\n",
|
| 1438 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python -m pip install spandrel==0.3.0''')\n",
|
| 1439 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python -m pip install opencv-python''')\n",
|
| 1440 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python -m pip install pydantic==1.10.15''')\n",
|
| 1441 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python -m pip install transformers -U''')\n",
|
| 1442 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python -m pip install llama-cpp-python''')\n",
|
| 1443 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python -m pip install pytorch_lightning==2.3.3 torchsde==0.2.6 spandrel==0.3.4''')\n",
|
| 1444 |
-
" \n",
|
| 1445 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python3 -m pip install open-clip-torch -U''')\n",
|
| 1446 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python3 -m pip install protobuf==4.25.8''')\n",
|
| 1447 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python3 -m pip install blendmodes==2022''')\n",
|
| 1448 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python3 -m pip install Pillow==9.5.0''')\n",
|
| 1449 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python3 -m pip install basicsr''')\n",
|
| 1450 |
-
" \n",
|
| 1451 |
-
" get_ipython().system(f'''{_install_path}/{_ui_dir_name}/venv/bin/python3 -m pip install basicsr''')\n",
|
| 1452 |
-
" \n",
|
| 1453 |
-
" envInstalled = True\n",
|
| 1454 |
-
" print('安装需要的python环境 完成')\n",
|
| 1455 |
-
" \n",
|
| 1456 |
-
"# 个性化配置 \n",
|
| 1457 |
-
"def use_config():\n",
|
| 1458 |
-
" print('使用自定义配置 包括tag翻译 \\n')\n",
|
| 1459 |
-
" run(f'''mkdir -p {_install_path}/temp''')\n",
|
| 1460 |
-
" run(f'git clone {_sd_config_git_repu} sd-configs',cwd=f'{_install_path}/temp')\n",
|
| 1461 |
-
" run(f'cp -r -f -n {_install_path}/temp/sd-configs/dist/* {_install_path}/{_ui_dir_name}')\n",
|
| 1462 |
-
" if not Path(_ui_config_file).exists() and _ui_config_file != 'ui-config.json': # ui配置文件\n",
|
| 1463 |
-
" run(f'''mkdir -p {_ui_config_file[:_ui_config_file.rfind('/')]}''')\n",
|
| 1464 |
-
" run(f'cp -f -n {_install_path}/{_ui_dir_name}/ui-config.json {_ui_config_file}')\n",
|
| 1465 |
-
" if not Path(_setting_file).exists() and _setting_file != 'config.json': # 设置配置文件\n",
|
| 1466 |
-
" run(f'''mkdir -p {_setting_file[:_setting_file.rfind('/')]}''')\n",
|
| 1467 |
-
" run(f'cp -f -n {_install_path}/{_ui_dir_name}/config.json {_setting_file}')\n",
|
| 1468 |
-
"\n",
|
| 1469 |
-
"def copy_last_log_to_images():\n",
|
| 1470 |
-
" if not Path(f'{_install_path}/{_ui_dir_name}/log/images').exists(): mkdirs(f'{_install_path}/{_ui_dir_name}/log/images')\n",
|
| 1471 |
-
" print('复制编号最大的一张收藏图到输出目录,用于保持编号,否则会出现收藏的图片被覆盖的情况')\n",
|
| 1472 |
-
" img_list = os.listdir(f'{_install_path}/{_ui_dir_name}/log/images')\n",
|
| 1473 |
-
" last_img_path = ''\n",
|
| 1474 |
-
" last_img_num = 0\n",
|
| 1475 |
-
" for img in img_list:\n",
|
| 1476 |
-
" if re.findall(r'^\\d+-',str(img)):\n",
|
| 1477 |
-
" num = int(re.findall(r'^\\d+-',str(img))[0][:-1])\n",
|
| 1478 |
-
" if num > last_img_num:\n",
|
| 1479 |
-
" last_img_path = img\n",
|
| 1480 |
-
" last_img_num = num\n",
|
| 1481 |
-
" \n",
|
| 1482 |
-
" if not last_img_path: return\n",
|
| 1483 |
-
" \n",
|
| 1484 |
-
" print(f'{_install_path}/{_ui_dir_name}/log/images/{last_img_path} {_install_path}/{_ui_dir_name}/outputs/txt2img-images')\n",
|
| 1485 |
-
" run(f'''mkdir -p {_install_path}/{_ui_dir_name}/outputs/txt2img-images''')\n",
|
| 1486 |
-
" run(f'''cp -f {_install_path}/{_ui_dir_name}/log/images/{last_img_path} {_install_path}/{_ui_dir_name}/outputs/txt2img-images/''')\n",
|
| 1487 |
-
" \n",
|
| 1488 |
-
" print(f'{_install_path}/{_ui_dir_name}/log/images/{last_img_path} {_install_path}/{_ui_dir_name}/outputs/img2img-images')\n",
|
| 1489 |
-
" run(f'''mkdir -p {_install_path}/{_ui_dir_name}/outputs/img2img-images''')\n",
|
| 1490 |
-
" run(f'''cp -f {_install_path}/{_ui_dir_name}/log/images/{last_img_path} {_install_path}/{_ui_dir_name}/outputs/img2img-images/''')\n",
|
| 1491 |
-
" \n",
|
| 1492 |
-
"def start_webui(i):\n",
|
| 1493 |
-
" # 只要不爆内存,其他方式关闭后会再次重启 访问地址会发生变化\n",
|
| 1494 |
-
" print(i,'--port',str(_server_port+1+i))\n",
|
| 1495 |
-
" if i>0:\n",
|
| 1496 |
-
" print(f'使用第{i+1}张显卡启动第{i+1}个服务,通过frpc或nrgok地址后加{_sub_path[i]}进行访问')\n",
|
| 1497 |
-
"\n",
|
| 1498 |
-
" restart_times = 0\n",
|
| 1499 |
-
" last_restart_time = time.time()\n",
|
| 1500 |
-
" while _runing:\n",
|
| 1501 |
-
" os.chdir(f'{_install_path}/{_ui_dir_name}')\n",
|
| 1502 |
-
" root_path = _sub_path[i]\n",
|
| 1503 |
-
" if root_path.endswith('/'): root_path = root_path[:-1]\n",
|
| 1504 |
-
" if torch.cuda.device_count() == 2 and not _multi_case:\n",
|
| 1505 |
-
" os.environ['CUDA_VISIBLE_DEVICES']='0,1'\n",
|
| 1506 |
-
" get_ipython().system(f'''venv/bin/python3 launch.py --port {str(_server_port+1+i)} --subpath={_sub_path[i]}''')\n",
|
| 1507 |
-
" else: \n",
|
| 1508 |
-
" get_ipython().system(f'''venv/bin/python3 launch.py --device-id={i} --port {str(_server_port+1+i)} --subpath={_sub_path[i]}''')\n",
|
| 1509 |
-
" print('10秒后重启服务')\n",
|
| 1510 |
-
" if time.time() - last_restart_time < 60:\n",
|
| 1511 |
-
" restart_times = restart_times + 1\n",
|
| 1512 |
-
" else:\n",
|
| 1513 |
-
" restart_times = 0\n",
|
| 1514 |
-
" last_restart_time = time.time()\n",
|
| 1515 |
-
" if restart_times >3 :\n",
|
| 1516 |
-
" # 如果180秒内重启了3此,将不再自动重启\n",
|
| 1517 |
-
" break\n",
|
| 1518 |
-
" time.sleep(10)\n",
|
| 1519 |
-
" \n",
|
| 1520 |
-
"# 启动\n",
|
| 1521 |
-
"def start():\n",
|
| 1522 |
-
" print('启动webui')\n",
|
| 1523 |
-
" os.chdir(f'''{_install_path}/{_ui_dir_name}''')\n",
|
| 1524 |
-
" args = ''\n",
|
| 1525 |
-
" if _ui_config_file is not None and _ui_config_file != '' and Path(_ui_config_file).exists(): # ui配置文件\n",
|
| 1526 |
-
" args += ' --ui-config-file=' + _ui_config_file\n",
|
| 1527 |
-
" if _setting_file is not None and _setting_file != '' and Path(_setting_file).exists(): # 设置配置文件\n",
|
| 1528 |
-
" args += ' --ui-settings-file=' + _setting_file\n",
|
| 1529 |
-
" args += ' ' + otherArgs\n",
|
| 1530 |
-
" os.environ['COMMANDLINE_ARGS']=args\n",
|
| 1531 |
-
" run(f'''echo COMMANDLINE_ARGS=$COMMANDLINE_ARGS''')\n",
|
| 1532 |
-
" os.environ['REQS_FILE']='requirements_versions.txt'\n",
|
| 1533 |
-
"\n",
|
| 1534 |
-
" with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:\n",
|
| 1535 |
-
" for i in range(torch.cuda.device_count() if _multi_case else 1):\n",
|
| 1536 |
-
" executor.submit(start_webui,i)\n",
|
| 1537 |
-
" while _runing and not check_service('localhost',str(_server_port+1+i)): # 当当前服务启动完成才允许退出此次循环\n",
|
| 1538 |
-
" time.sleep(5)\n",
|
| 1539 |
-
" if not _runing: break\n",
|
| 1540 |
-
" time.sleep(10)"
|
| 1541 |
-
]
|
| 1542 |
-
},
|
| 1543 |
-
{
|
| 1544 |
-
"cell_type": "markdown",
|
| 1545 |
-
"metadata": {
|
| 1546 |
-
"id": "qLvsk8ByLCtF"
|
| 1547 |
-
},
|
| 1548 |
-
"source": [
|
| 1549 |
-
"# 入口函数\n",
|
| 1550 |
-
"---"
|
| 1551 |
-
]
|
| 1552 |
-
},
|
| 1553 |
-
{
|
| 1554 |
-
"cell_type": "code",
|
| 1555 |
-
"execution_count": null,
|
| 1556 |
-
"metadata": {
|
| 1557 |
-
"_kg_hide-input": true,
|
| 1558 |
-
"id": "IOKjaMlcLCtF",
|
| 1559 |
-
"trusted": true
|
| 1560 |
-
},
|
| 1561 |
-
"outputs": [],
|
| 1562 |
-
"source": [
|
| 1563 |
-
"\n",
|
| 1564 |
-
"# 启动非webui相关的的内容,加快启动速度\n",
|
| 1565 |
-
"def main():\n",
|
| 1566 |
-
" global envInstalled\n",
|
| 1567 |
-
" global huggingface_is_init\n",
|
| 1568 |
-
" global _runing\n",
|
| 1569 |
-
" _init_conf()\n",
|
| 1570 |
-
" stop_solo_threads()\n",
|
| 1571 |
-
" print('启动...')\n",
|
| 1572 |
-
" startTicks = time.time()\n",
|
| 1573 |
-
" time.sleep(5)\n",
|
| 1574 |
-
" _runing = True\n",
|
| 1575 |
-
" isInstall = True if os.getenv('IsInstall','False') == 'True' else False\n",
|
| 1576 |
-
" _proxy_path[_sub_path[0]] = f'http://127.0.0.1:{_server_port+1}/'\n",
|
| 1577 |
-
" _proxy_path[_sub_path[1]] = f'http://127.0.0.1:{_server_port+2}/'\n",
|
| 1578 |
-
" proxy_thread = threading.Thread(target = startProxy, daemon=True, name='solo_startProxy')\n",
|
| 1579 |
-
" proxy_thread.start()\n",
|
| 1580 |
-
" if isInstall is False or _reLoad: \n",
|
| 1581 |
-
" print('安装运行环境')\n",
|
| 1582 |
-
" os.environ['MPLBACKEND'] = 'Agg'\n",
|
| 1583 |
-
" install()\n",
|
| 1584 |
-
" link_dir()\n",
|
| 1585 |
-
" init_huggingface()\n",
|
| 1586 |
-
" install_optimizing()\n",
|
| 1587 |
-
" if not _skip_webui:\n",
|
| 1588 |
-
" threading.Thread(target = install_dependencies,daemon=True,name='solo_install_dependencies').start()\n",
|
| 1589 |
-
" else: envInstalled = True\n",
|
| 1590 |
-
" link_or_download_flie(replace_path(_async_downloading), _link_instead_of_copy=_link_instead_of_copy,\n",
|
| 1591 |
-
" base_path=f'{_install_path}/{_ui_dir_name}')\n",
|
| 1592 |
-
" if huggingface_is_init:\n",
|
| 1593 |
-
" threading.Thread(target = download__huggingface_repo,daemon=True,\n",
|
| 1594 |
-
" args=([_huggingface_repo]),\n",
|
| 1595 |
-
" kwargs={\"callback\":copy_last_log_to_images},\n",
|
| 1596 |
-
" name='solo_download__huggingface_repo').start()\n",
|
| 1597 |
-
" \n",
|
| 1598 |
-
" link_or_download_flie(replace_path(_before_downloading), _link_instead_of_copy=_link_instead_of_copy,\n",
|
| 1599 |
-
" base_path=f'{_install_path}/{_ui_dir_name}',is_await=True,sync=True)\n",
|
| 1600 |
-
" t = 0\n",
|
| 1601 |
-
" while _runing and not envInstalled:\n",
|
| 1602 |
-
" if t%10==0:\n",
|
| 1603 |
-
" print('等待python环境安装...')\n",
|
| 1604 |
-
" t = t+1\n",
|
| 1605 |
-
" time.sleep(1)\n",
|
| 1606 |
-
" use_config()\n",
|
| 1607 |
-
" os.environ['IsInstall'] = 'True'\n",
|
| 1608 |
-
" else:\n",
|
| 1609 |
-
" envInstalled = True\n",
|
| 1610 |
-
" localProxy()\n",
|
| 1611 |
-
" link_or_download_flie(replace_path(_before_start_sync_downloading), _link_instead_of_copy=_link_instead_of_copy,\n",
|
| 1612 |
-
" base_path=f'{_install_path}/{_ui_dir_name}',sync=True)\n",
|
| 1613 |
-
" if init_huggingface():\n",
|
| 1614 |
-
" start_sync_log_to_huggingface(_huggingface_repo)\n",
|
| 1615 |
-
" ticks = time.time()\n",
|
| 1616 |
-
" _on_before_start()\n",
|
| 1617 |
-
" print(\"加载耗时:\",(ticks - startTicks),\"秒\")\n",
|
| 1618 |
-
" if _skip_webui:\n",
|
| 1619 |
-
" print('跳过webui启动')\n",
|
| 1620 |
-
" proxy_thread.join()\n",
|
| 1621 |
-
" else:\n",
|
| 1622 |
-
" start()\n"
|
| 1623 |
-
]
|
| 1624 |
-
},
|
| 1625 |
-
{
|
| 1626 |
-
"cell_type": "markdown",
|
| 1627 |
-
"metadata": {
|
| 1628 |
-
"id": "0oaCRs2gLCtF"
|
| 1629 |
-
},
|
| 1630 |
-
"source": [
|
| 1631 |
-
"# 执行区域\n",
|
| 1632 |
-
"---"
|
| 1633 |
-
]
|
| 1634 |
-
},
|
| 1635 |
-
{
|
| 1636 |
-
"cell_type": "code",
|
| 1637 |
-
"execution_count": null,
|
| 1638 |
-
"metadata": {
|
| 1639 |
-
"_kg_hide-output": true,
|
| 1640 |
-
"id": "O3DR0DWHLCtF",
|
| 1641 |
-
"scrolled": true,
|
| 1642 |
-
"trusted": true
|
| 1643 |
-
},
|
| 1644 |
-
"outputs": [],
|
| 1645 |
-
"source": [
|
| 1646 |
-
"# 启动\n",
|
| 1647 |
-
"# _reLoad = True\n",
|
| 1648 |
-
"# hidden_console_info = False\n",
|
| 1649 |
-
"# run_by_none_device = True\n",
|
| 1650 |
-
"# show_shell_info = True\n",
|
| 1651 |
-
"\n",
|
| 1652 |
-
"print(f'当前sd的安装路径是:{_install_path}/{_ui_dir_name}')\n",
|
| 1653 |
-
"print(f'当前图片保存路径是:{_output_path}')\n",
|
| 1654 |
-
"print(f'当前数据集路径是:{_input_path}')\n",
|
| 1655 |
-
"\n",
|
| 1656 |
-
"print(update_desc)\n",
|
| 1657 |
-
"\n",
|
| 1658 |
-
"if _skip_start:\n",
|
| 1659 |
-
" print('已跳过自动启动,可手动执行 main() 进行启动。')\n",
|
| 1660 |
-
" print('''推荐的启动代码:\n",
|
| 1661 |
-
"try:\n",
|
| 1662 |
-
" check_gpu() # 检查是否存在gpu\n",
|
| 1663 |
-
" main()\n",
|
| 1664 |
-
"except KeyboardInterrupt:\n",
|
| 1665 |
-
" stop_solo_threads() # 中断后自动停止后台线程 (有部分功能在后台线程中运行)\n",
|
| 1666 |
-
" ''')\n",
|
| 1667 |
-
"else:\n",
|
| 1668 |
-
" try:\n",
|
| 1669 |
-
" check_gpu()\n",
|
| 1670 |
-
" main()\n",
|
| 1671 |
-
" except KeyboardInterrupt:\n",
|
| 1672 |
-
" stop_solo_threads()"
|
| 1673 |
-
]
|
| 1674 |
-
},
|
| 1675 |
-
{
|
| 1676 |
-
"cell_type": "code",
|
| 1677 |
-
"execution_count": null,
|
| 1678 |
-
"metadata": {
|
| 1679 |
-
"trusted": true
|
| 1680 |
-
},
|
| 1681 |
-
"outputs": [],
|
| 1682 |
-
"source": []
|
| 1683 |
-
}
|
| 1684 |
-
],
|
| 1685 |
-
"metadata": {
|
| 1686 |
-
"kaggle": {
|
| 1687 |
-
"accelerator": "nvidiaTeslaT4",
|
| 1688 |
-
"dataSources": [
|
| 1689 |
-
{
|
| 1690 |
-
"datasetId": 2716934,
|
| 1691 |
-
"sourceId": 6167400,
|
| 1692 |
-
"sourceType": "datasetVersion"
|
| 1693 |
-
},
|
| 1694 |
-
{
|
| 1695 |
-
"datasetId": 3654544,
|
| 1696 |
-
"sourceId": 6346544,
|
| 1697 |
-
"sourceType": "datasetVersion"
|
| 1698 |
-
},
|
| 1699 |
-
{
|
| 1700 |
-
"datasetId": 2962375,
|
| 1701 |
-
"sourceId": 6720235,
|
| 1702 |
-
"sourceType": "datasetVersion"
|
| 1703 |
-
},
|
| 1704 |
-
{
|
| 1705 |
-
"datasetId": 3074484,
|
| 1706 |
-
"sourceId": 6817788,
|
| 1707 |
-
"sourceType": "datasetVersion"
|
| 1708 |
-
}
|
| 1709 |
-
],
|
| 1710 |
-
"isGpuEnabled": true,
|
| 1711 |
-
"isInternetEnabled": true,
|
| 1712 |
-
"language": "python",
|
| 1713 |
-
"sourceType": "notebook"
|
| 1714 |
-
},
|
| 1715 |
-
"kernelspec": {
|
| 1716 |
-
"display_name": "Python 3",
|
| 1717 |
-
"language": "python",
|
| 1718 |
-
"name": "python3"
|
| 1719 |
-
},
|
| 1720 |
-
"language_info": {
|
| 1721 |
-
"codemirror_mode": {
|
| 1722 |
-
"name": "ipython",
|
| 1723 |
-
"version": 3
|
| 1724 |
-
},
|
| 1725 |
-
"file_extension": ".py",
|
| 1726 |
-
"mimetype": "text/x-python",
|
| 1727 |
-
"name": "python",
|
| 1728 |
-
"nbconvert_exporter": "python",
|
| 1729 |
-
"pygments_lexer": "ipython3",
|
| 1730 |
-
"version": "3.10.13"
|
| 1731 |
-
}
|
| 1732 |
-
},
|
| 1733 |
-
"nbformat": 4,
|
| 1734 |
-
"nbformat_minor": 4
|
| 1735 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sdwui-start-util.mini.ipynb
DELETED
|
@@ -1,1652 +0,0 @@
|
|
| 1 |
-
{
|
| 2 |
-
"cells": [
|
| 3 |
-
{
|
| 4 |
-
"cell_type": "code",
|
| 5 |
-
"execution_count": null,
|
| 6 |
-
"metadata": {
|
| 7 |
-
"trusted": true
|
| 8 |
-
},
|
| 9 |
-
"outputs": [],
|
| 10 |
-
"source": []
|
| 11 |
-
},
|
| 12 |
-
{
|
| 13 |
-
"cell_type": "code",
|
| 14 |
-
"execution_count": null,
|
| 15 |
-
"metadata": {
|
| 16 |
-
"trusted": true
|
| 17 |
-
},
|
| 18 |
-
"outputs": [],
|
| 19 |
-
"source": [
|
| 20 |
-
"update_desc = '''\n",
|
| 21 |
-
"欢迎使用 stable-diffusion-webui 便捷启动工具\n",
|
| 22 |
-
"\n",
|
| 23 |
-
"此脚本理论上可以在任何jupyter环境运行,但仅在 google colab 和 kaggle 测试。 已经无法在 google colab 免费实例上运行。\n",
|
| 24 |
-
"此脚本的【前置脚本】发布地址 https://www.kaggle.com/code/yiyiooo/stable-diffusion-webui-novelai-sdxl。\n",
|
| 25 |
-
"此脚本需配合 【前置脚本】 的脚本附带的配置项才能正常启动。\n",
|
| 26 |
-
"此脚本的内容会自动更新,你无需更新【前置脚本】就能获取到最新的功能。\n",
|
| 27 |
-
"增加一个说明:为解决加密图片的解密和浏览的问题,开发了一个独立应用,可以在这里下载 https://github.com/viyiviyi/encrypt_gallery/releases/\n",
|
| 28 |
-
"加密插件可解决生成nsfw图片后被平台封号问题\n",
|
| 29 |
-
"\n",
|
| 30 |
-
"路径说明\n",
|
| 31 |
-
"* 为了解决平台差异,所有的安装目录和文件输出目录都被重新指定,如果你需要在配置中访问这些目录,请查看以下说明\n",
|
| 32 |
-
"*\n",
|
| 33 |
-
"* 可以使用 $install_path 或 {install_path} 来访问安装目录,写在字符串内也会生效\n",
|
| 34 |
-
"* $output_path 或 {output_path} 可以访问输出目录\n",
|
| 35 |
-
"* 如果你需要安装在自定义目录,也可以设置这些值 如: install_path = '新的路径'\n",
|
| 36 |
-
"* 可自定义方法 on_before_start 并在方法内写上启动前需要的逻辑来实现在webui启动前执行自定义逻辑\n",
|
| 37 |
-
"* 可以增加配置 multi_case = True 来控制是否使用多卡\n",
|
| 38 |
-
"* 如果需要显示更多控制台输出 需配置 hidden_console_info = False\n",
|
| 39 |
-
"\n",
|
| 40 |
-
"********* 特别提示 *********\n",
|
| 41 |
-
"* huggingface 的下载链接需要增加 ?download=true 参数才能正确下载到文件,如果你需要的文件里的下载链接没有这个参数,请自行增加。\n",
|
| 42 |
-
"'''"
|
| 43 |
-
]
|
| 44 |
-
},
|
| 45 |
-
{
|
| 46 |
-
"cell_type": "code",
|
| 47 |
-
"execution_count": null,
|
| 48 |
-
"metadata": {
|
| 49 |
-
"trusted": true
|
| 50 |
-
},
|
| 51 |
-
"outputs": [],
|
| 52 |
-
"source": [
|
| 53 |
-
"from pathlib import Path\n",
|
| 54 |
-
"import os\n",
|
| 55 |
-
"import time\n",
|
| 56 |
-
"import re\n",
|
| 57 |
-
"import subprocess\n",
|
| 58 |
-
"import threading\n",
|
| 59 |
-
"import sys\n",
|
| 60 |
-
"import socket\n",
|
| 61 |
-
"import torch\n",
|
| 62 |
-
"from typing import List\n",
|
| 63 |
-
"import uuid\n",
|
| 64 |
-
"import asyncio\n",
|
| 65 |
-
"from urllib import request"
|
| 66 |
-
]
|
| 67 |
-
},
|
| 68 |
-
{
|
| 69 |
-
"cell_type": "code",
|
| 70 |
-
"execution_count": null,
|
| 71 |
-
"metadata": {
|
| 72 |
-
"trusted": true
|
| 73 |
-
},
|
| 74 |
-
"outputs": [],
|
| 75 |
-
"source": [
|
| 76 |
-
"# 内置参数默认值,当上下文有参数时可覆盖默认值\n",
|
| 77 |
-
"_runing = False\n",
|
| 78 |
-
"_useFrpc = True\n",
|
| 79 |
-
"_useNgrok = True\n",
|
| 80 |
-
"_reLoad = False\n",
|
| 81 |
-
"_before_downloading = ''\n",
|
| 82 |
-
"_async_downloading = ''\n",
|
| 83 |
-
"_before_start_sync_downloading = ''\n",
|
| 84 |
-
"_server_port = 7860\n",
|
| 85 |
-
"_sd_git_repo = 'https://github.com/viyiviyi/stable-diffusion-webui.git -b local'\n",
|
| 86 |
-
"_sd_config_git_repu = 'https://github.com/viyiviyi/sd-configs.git'\n",
|
| 87 |
-
"_huggingface_token = '{input_path}/configs/huggingface_token.txt'\n",
|
| 88 |
-
"_huggingface_repo = ''\n",
|
| 89 |
-
"_link_instead_of_copy = True\n",
|
| 90 |
-
"show_shell_info = False\n",
|
| 91 |
-
"_multi_case = False\n",
|
| 92 |
-
"_skip_start = True\n",
|
| 93 |
-
"def before_start():\n",
|
| 94 |
-
" pass\n",
|
| 95 |
-
"\n",
|
| 96 |
-
"def main_start():\n",
|
| 97 |
-
" pass\n",
|
| 98 |
-
" \n",
|
| 99 |
-
"_on_before_start = before_start \n",
|
| 100 |
-
"_skip_webui = False\n",
|
| 101 |
-
"run_by_none_device = False\n",
|
| 102 |
-
"_proxy_path = {}\n",
|
| 103 |
-
"_sub_path = ['/','/1/']\n",
|
| 104 |
-
"_config_args:dict[str, str] = {}"
|
| 105 |
-
]
|
| 106 |
-
},
|
| 107 |
-
{
|
| 108 |
-
"cell_type": "code",
|
| 109 |
-
"execution_count": null,
|
| 110 |
-
"metadata": {
|
| 111 |
-
"trusted": true
|
| 112 |
-
},
|
| 113 |
-
"outputs": [],
|
| 114 |
-
"source": [
|
| 115 |
-
"\n",
|
| 116 |
-
"def run(command, cwd=None, desc=None, errdesc=None, custom_env=None,try_error:bool=True) -> str:\n",
|
| 117 |
-
" global show_shell_info\n",
|
| 118 |
-
" if desc is not None:\n",
|
| 119 |
-
" print(desc)\n",
|
| 120 |
-
"\n",
|
| 121 |
-
" run_kwargs = {\n",
|
| 122 |
-
" \"args\": command,\n",
|
| 123 |
-
" \"shell\": True,\n",
|
| 124 |
-
" \"cwd\": cwd,\n",
|
| 125 |
-
" \"env\": os.environ if custom_env is None else custom_env,\n",
|
| 126 |
-
" \"encoding\": 'utf8',\n",
|
| 127 |
-
" \"errors\": 'ignore',\n",
|
| 128 |
-
" }\n",
|
| 129 |
-
"\n",
|
| 130 |
-
" if not show_shell_info:\n",
|
| 131 |
-
" run_kwargs[\"stdout\"] = run_kwargs[\"stderr\"] = subprocess.PIPE\n",
|
| 132 |
-
"\n",
|
| 133 |
-
" result = subprocess.run(**run_kwargs)\n",
|
| 134 |
-
"\n",
|
| 135 |
-
" if result.returncode != 0:\n",
|
| 136 |
-
" error_bits = [\n",
|
| 137 |
-
" f\"{errdesc or 'Error running command'}.\",\n",
|
| 138 |
-
" f\"Command: {command}\",\n",
|
| 139 |
-
" f\"Error code: {result.returncode}\",\n",
|
| 140 |
-
" ]\n",
|
| 141 |
-
" if result.stdout:\n",
|
| 142 |
-
" error_bits.append(f\"stdout: {result.stdout}\")\n",
|
| 143 |
-
" if result.stderr:\n",
|
| 144 |
-
" error_bits.append(f\"stderr: {result.stderr}\")\n",
|
| 145 |
-
" if try_error:\n",
|
| 146 |
-
" print((RuntimeError(\"\\n\".join(error_bits))))\n",
|
| 147 |
-
" else:\n",
|
| 148 |
-
" raise RuntimeError(\"\\n\".join(error_bits))\n",
|
| 149 |
-
"\n",
|
| 150 |
-
" if show_shell_info:\n",
|
| 151 |
-
" print((result.stdout or \"\"))\n",
|
| 152 |
-
" return (result.stdout or \"\")\n",
|
| 153 |
-
"\n",
|
| 154 |
-
"def mkdirs(path, exist_ok=True):\n",
|
| 155 |
-
" if path and not Path(path).exists():\n",
|
| 156 |
-
" os.makedirs(path,exist_ok=exist_ok)\n",
|
| 157 |
-
"\n",
|
| 158 |
-
"\n",
|
| 159 |
-
"# 检查网络\n",
|
| 160 |
-
"def check_service(host, port):\n",
|
| 161 |
-
" try:\n",
|
| 162 |
-
" socket.create_connection((host, port), timeout=5)\n",
|
| 163 |
-
" return True\n",
|
| 164 |
-
" except socket.error:\n",
|
| 165 |
-
" return False\n",
|
| 166 |
-
"\n",
|
| 167 |
-
"\n",
|
| 168 |
-
"# 检查gpu是否存在\n",
|
| 169 |
-
"def check_gpu():\n",
|
| 170 |
-
" if not run_by_none_device and torch.cuda.device_count() == 0:\n",
|
| 171 |
-
" raise Exception('当前环境没有GPU')\n",
|
| 172 |
-
"\n",
|
| 173 |
-
"\n",
|
| 174 |
-
"def echoToFile(content:str,path:str):\n",
|
| 175 |
-
" if path.find('/') >= 0:\n",
|
| 176 |
-
" _path = '/'.join(path.split('/')[:-1])\n",
|
| 177 |
-
" run(f'''mkdir -p {_path}''')\n",
|
| 178 |
-
" with open(path,'w') as sh:\n",
|
| 179 |
-
" sh.write(content)\n",
|
| 180 |
-
" \n",
|
| 181 |
-
"def get_freefrp_confog(local_port):\n",
|
| 182 |
-
" rd_str = uuid.uuid1()\n",
|
| 183 |
-
" return (f'''\n",
|
| 184 |
-
"[common]\n",
|
| 185 |
-
"server_addr = frp.freefrp.net\n",
|
| 186 |
-
"server_port = 7000\n",
|
| 187 |
-
"token = freefrp.net\n",
|
| 188 |
-
"\n",
|
| 189 |
-
"[{rd_str}_http]\n",
|
| 190 |
-
"type = http\n",
|
| 191 |
-
"local_ip = 127.0.0.1\n",
|
| 192 |
-
"local_port = {local_port}\n",
|
| 193 |
-
"custom_domains = {rd_str}.frp.eaias.com\n",
|
| 194 |
-
"''',f'http://{rd_str}.frp.eaias.com')"
|
| 195 |
-
]
|
| 196 |
-
},
|
| 197 |
-
{
|
| 198 |
-
"cell_type": "code",
|
| 199 |
-
"execution_count": null,
|
| 200 |
-
"metadata": {
|
| 201 |
-
"trusted": true
|
| 202 |
-
},
|
| 203 |
-
"outputs": [],
|
| 204 |
-
"source": [
|
| 205 |
-
"\n",
|
| 206 |
-
"_install_path = f\"/kaggle\" if os.path.exists('/kaggle/') else f\"{os.environ['HOME']}/sd_webui\" # 安装目录\n",
|
| 207 |
-
"_output_path = '/kaggle/working' if os.path.exists('/kaggle/working/') else f\"{os.environ['HOME']}/.sdwui/Output\" # 输出目录 如果使用google云盘 会在google云盘增加sdwebui/Output\n",
|
| 208 |
-
"_input_path = '/kaggle/input' # 输入目录\n",
|
| 209 |
-
"_ui_dir_name = 'sd_main_dir'\n",
|
| 210 |
-
"\n",
|
| 211 |
-
"_install_path = locals().get('install_path') or globals().get('install_path') or _install_path\n",
|
| 212 |
-
"_output_path = locals().get('output_path') or globals().get('output_path') or _output_path\n",
|
| 213 |
-
"_input_path = locals().get('input_path') or globals().get('input_path') or _input_path\n",
|
| 214 |
-
"_ui_dir_name = locals().get('ui_dir_name') or globals().get('ui_dir_name') or _ui_dir_name\n",
|
| 215 |
-
"\n",
|
| 216 |
-
"install_path = _install_path\n",
|
| 217 |
-
"output_path = _output_path\n",
|
| 218 |
-
"input_path = _input_path\n",
|
| 219 |
-
"ui_dir_name = _ui_dir_name\n",
|
| 220 |
-
" \n",
|
| 221 |
-
"google_drive = '' \n",
|
| 222 |
-
"\n",
|
| 223 |
-
"\n",
|
| 224 |
-
"_useGooglrDrive = locals().get('useGooglrDrive') or globals().get('useGooglrDrive') or True\n",
|
| 225 |
-
"\n",
|
| 226 |
-
"# 连接谷歌云\n",
|
| 227 |
-
"try:\n",
|
| 228 |
-
" if _useGooglrDrive:\n",
|
| 229 |
-
" from google.colab import drive\n",
|
| 230 |
-
" drive.mount(f'~/google_drive')\n",
|
| 231 |
-
" google_drive = f\"{os.environ['HOME']}/google_drive/MyDrive\"\n",
|
| 232 |
-
" _output_path = f'{google_drive}/sdwebui/Output'\n",
|
| 233 |
-
" _input_path = f'{google_drive}/sdwebui/Input'\n",
|
| 234 |
-
" run(f'''mkdir -p {_input_path}''')\n",
|
| 235 |
-
" print('''\n",
|
| 236 |
-
"已经链接到谷歌云盘\n",
|
| 237 |
-
"已在云盘创建Input和Output目录\n",
|
| 238 |
-
" ''')\n",
|
| 239 |
-
"except:\n",
|
| 240 |
-
" _useGooglrDrive = False\n",
|
| 241 |
-
"\n",
|
| 242 |
-
"run(f'''mkdir -p {_install_path}''')\n",
|
| 243 |
-
"run(f'''mkdir -p {_output_path}''')\n",
|
| 244 |
-
"\n",
|
| 245 |
-
"\n",
|
| 246 |
-
"os.environ['install_path'] = _install_path\n",
|
| 247 |
-
"os.environ['output_path'] = _output_path\n",
|
| 248 |
-
"os.environ['google_drive'] = google_drive\n",
|
| 249 |
-
"os.environ['input_path'] = _input_path\n",
|
| 250 |
-
"\n",
|
| 251 |
-
"space_string = ' \\n\\r\\t\\'\\\",'\n",
|
| 252 |
-
"\n",
|
| 253 |
-
"def replace_path(input_str:str):\n",
|
| 254 |
-
" if not input_str: return ''\n",
|
| 255 |
-
" for key in _config_args:\n",
|
| 256 |
-
" input_str = input_str.replace(key,_config_args[key])\n",
|
| 257 |
-
" \n",
|
| 258 |
-
" if not (locals().get('use_comfyui') or globals().get('use_comfyui') or False):\n",
|
| 259 |
-
" input_str = input_str.replace('https://github.com/comfyanonymous/ComfyUI.git','https://github.com/comfyanonymous/ComfyUI.git')\n",
|
| 260 |
-
" \n",
|
| 261 |
-
" return input_str.replace('$install_path',_install_path)\\\n",
|
| 262 |
-
" .replace('{install_path}',_install_path)\\\n",
|
| 263 |
-
" .replace('$input_path',_input_path)\\\n",
|
| 264 |
-
" .replace('{input_path}',_input_path)\\\n",
|
| 265 |
-
" .replace('$output_path',_output_path)\\\n",
|
| 266 |
-
" .replace('{output_path}',_output_path)\\\n",
|
| 267 |
-
" .replace('{sdwui}','stable-diffusion-webui')\\\n",
|
| 268 |
-
" .replace('{wui}',\"webui\")\\\n",
|
| 269 |
-
" .strip()\n",
|
| 270 |
-
"\n",
|
| 271 |
-
"\n",
|
| 272 |
-
"def config_reader(conf:str):\n",
|
| 273 |
-
" conf = conf or \"\"\n",
|
| 274 |
-
" args = [replace_path(item.split('#')[0].strip(space_string)) for item in conf.split('\\n') if item.strip(space_string)]\n",
|
| 275 |
-
" return [item.strip() for item in args if item.strip()]\n",
|
| 276 |
-
"\n",
|
| 277 |
-
"def load_frpc_config(conf_or_file,dost_port=None):\n",
|
| 278 |
-
" frpcStartArg = ''\n",
|
| 279 |
-
" _frp_temp_config_file = ''\n",
|
| 280 |
-
" _frp_config_or_file = conf_or_file\n",
|
| 281 |
-
" run(f'''mkdir -p {_install_path}/configFiles''')\n",
|
| 282 |
-
" if _frp_config_or_file:\n",
|
| 283 |
-
" if '[common]' in _frp_config_or_file:\n",
|
| 284 |
-
" echoToFile(_frp_config_or_file,f'{_install_path}/configFiles/temp_frpc_{dost_port or _server_port}.ini')\n",
|
| 285 |
-
" _frp_temp_config_file = f'{_install_path}/configFiles/temp_frpc_{dost_port or _server_port}.ini'\n",
|
| 286 |
-
" elif '.ini' in _frp_config_or_file:\n",
|
| 287 |
-
" _frp_temp_config_file = _frp_config_or_file.strip()\n",
|
| 288 |
-
" \n",
|
| 289 |
-
" if _frp_temp_config_file:\n",
|
| 290 |
-
" if Path(_frp_temp_config_file).exists():\n",
|
| 291 |
-
" run(f'''cp -f {_frp_temp_config_file} {_install_path}/configFiles/frpc_{dost_port or _server_port}.ini''')\n",
|
| 292 |
-
" run(f'''sed -i \"s/local_port = .*/local_port = {dost_port or _server_port}/g\" {_install_path}/configFiles/frpc_{dost_port or _server_port}.ini''')\n",
|
| 293 |
-
" frpcStartArg = f' -c {_install_path}/configFiles/frpc_{dost_port or _server_port}.ini'\n",
|
| 294 |
-
" elif _frp_config_or_file.strip().startswith('-f'):\n",
|
| 295 |
-
" frpcStartArg = _frp_config_or_file.strip()\n",
|
| 296 |
-
" return frpcStartArg"
|
| 297 |
-
]
|
| 298 |
-
},
|
| 299 |
-
{
|
| 300 |
-
"cell_type": "code",
|
| 301 |
-
"execution_count": null,
|
| 302 |
-
"metadata": {
|
| 303 |
-
"_kg_hide-input": true,
|
| 304 |
-
"id": "i3LhnwYHLCtC",
|
| 305 |
-
"trusted": true
|
| 306 |
-
},
|
| 307 |
-
"outputs": [],
|
| 308 |
-
"source": [
|
| 309 |
-
"ngrokTokenFile = os.path.join(_input_path,'configs/ngrok_token.txt') # 非必填 存放ngrokToken的文件的路径\n",
|
| 310 |
-
"frpcConfigFile = os.path.join(_input_path,'configs/frpc_koishi.ini') # 非必填 frp 配置文件\n",
|
| 311 |
-
"# ss证书目录 下载nginx的版本,把pem格式改成crt格式\n",
|
| 312 |
-
"frpcSSLFFlies = [os.path.join(_input_path,'configs/koishi_ssl')]\n",
|
| 313 |
-
"if 'frp_ssl_dir' in locals() or 'frp_ssl_dir' in globals():\n",
|
| 314 |
-
" frpcSSLFFlies = frpcSSLFFlies + config_reader(locals().get('frp_ssl_dir') or globals().get('frp_ssl_dir'))\n",
|
| 315 |
-
"# frpc 文件目录 如果目录不存在,会自动下载,也可以在数据集搜索 viyiviyi/utils 添加\n",
|
| 316 |
-
"frpcExePath = os.path.join(_input_path,'utils-tools/frpc')\n",
|
| 317 |
-
"# 其他需要加载的webui启动参数 写到【参数列表】这个配置去\n",
|
| 318 |
-
"otherArgs = '--xformers'\n",
|
| 319 |
-
"if 'sd_start_args' in locals() or 'sd_start_args' in globals():\n",
|
| 320 |
-
" otherArgs = ' '.join([item for item in config_reader(locals().get('sd_start_args') or globals().get('sd_start_args')) if item != '--no-gradio-queue'])\n",
|
| 321 |
-
"venvPath = os.path.join(_input_path,'sd-webui-venv-mini/venv.tar.bak') # 安装好的python环境 sd-webui-venv是一个公开是数据集 可以搜索添加\n",
|
| 322 |
-
"if not Path(venvPath).exists():\n",
|
| 323 |
-
" venvPath = os.path.join(_input_path,'sd-webui-venv-mini/venv.zip')\n",
|
| 324 |
-
"\n",
|
| 325 |
-
"# 用于使用kaggle api的token文件 参考 https://www.kaggle.com/docs/api\n",
|
| 326 |
-
"# 此文件用于自动上传koishi的相关配置 也可以用于保存重要的输出文件\n",
|
| 327 |
-
"kaggleApiTokenFile = os.path.join(_input_path,'configs/kaggle.json')\n",
|
| 328 |
-
"\n",
|
| 329 |
-
"requirements = []\n"
|
| 330 |
-
]
|
| 331 |
-
},
|
| 332 |
-
{
|
| 333 |
-
"cell_type": "code",
|
| 334 |
-
"execution_count": null,
|
| 335 |
-
"metadata": {
|
| 336 |
-
"_kg_hide-input": true,
|
| 337 |
-
"id": "a_GtG2ayLCtD",
|
| 338 |
-
"trusted": true
|
| 339 |
-
},
|
| 340 |
-
"outputs": [],
|
| 341 |
-
"source": [
|
| 342 |
-
"# 这下面的是用于初始化一些值或者环境变量的,轻易别改\n",
|
| 343 |
-
"_setting_file = replace_path(locals().get('setting_file') or globals().get('setting_file') or 'config.json')\n",
|
| 344 |
-
"\n",
|
| 345 |
-
"_ui_config_file = replace_path(locals().get('ui_config_file') or globals().get('ui_config_file') or 'ui-config.json')\n",
|
| 346 |
-
"\n",
|
| 347 |
-
"# 设置文件路径\n",
|
| 348 |
-
"if Path(f\"{os.environ['HOME']}/google_drive/MyDrive\").exists():\n",
|
| 349 |
-
" if _setting_file == '/kaggle/working/configs/config.json':\n",
|
| 350 |
-
" _setting_file = os.path.join(_output_path,'configs/config.json')\n",
|
| 351 |
-
" if _ui_config_file == '/kaggle/working/configs/ui-config.json':\n",
|
| 352 |
-
" _ui_config_file = os.path.join(_output_path,'configs/ui-config.json')\n",
|
| 353 |
-
" \n",
|
| 354 |
-
"frpcStartArg = load_frpc_config(replace_path(locals().get('frp_config_or_file') or globals().get('frp_config_or_file')) or '', _server_port)\n",
|
| 355 |
-
"freefrp_url = ''\n",
|
| 356 |
-
"ngrokToken=''\n",
|
| 357 |
-
"_ngrok_config_or_file = replace_path(locals().get('ngrok_config_or_file') or globals().get('ngrok_config_or_file')) or ngrokTokenFile\n",
|
| 358 |
-
"if _ngrok_config_or_file:\n",
|
| 359 |
-
" if Path(_ngrok_config_or_file.strip()).exists():\n",
|
| 360 |
-
" ngrokTokenFile = _ngrok_config_or_file.strip()\n",
|
| 361 |
-
" if Path(ngrokTokenFile).exists():\n",
|
| 362 |
-
" with open(ngrokTokenFile,encoding = \"utf-8\") as nkfile:\n",
|
| 363 |
-
" ngrokToken = nkfile.readline()\n",
|
| 364 |
-
" elif not _ngrok_config_or_file.strip().startswith('/'):\n",
|
| 365 |
-
" ngrokToken=_ngrok_config_or_file.strip()\n",
|
| 366 |
-
" \n",
|
| 367 |
-
" \n",
|
| 368 |
-
"huggingface_headers:dict = None "
|
| 369 |
-
]
|
| 370 |
-
},
|
| 371 |
-
{
|
| 372 |
-
"cell_type": "code",
|
| 373 |
-
"execution_count": null,
|
| 374 |
-
"metadata": {
|
| 375 |
-
"trusted": true
|
| 376 |
-
},
|
| 377 |
-
"outputs": [],
|
| 378 |
-
"source": [
|
| 379 |
-
"def init_start_conf():\n",
|
| 380 |
-
" global _useFrpc\n",
|
| 381 |
-
" global _useNgrok\n",
|
| 382 |
-
" global _reLoad\n",
|
| 383 |
-
" global _before_downloading\n",
|
| 384 |
-
" global _async_downloading\n",
|
| 385 |
-
" global _before_start_sync_downloading\n",
|
| 386 |
-
" global _server_port\n",
|
| 387 |
-
" global _sd_git_repo\n",
|
| 388 |
-
" global _sd_config_git_repu\n",
|
| 389 |
-
" global _huggingface_token\n",
|
| 390 |
-
" global _huggingface_repo\n",
|
| 391 |
-
" global _link_instead_of_copy\n",
|
| 392 |
-
" global show_shell_info\n",
|
| 393 |
-
" global _multi_case\n",
|
| 394 |
-
" global _skip_start\n",
|
| 395 |
-
" global _on_before_start\n",
|
| 396 |
-
" global _skip_webui\n",
|
| 397 |
-
" global _proxy_path\n",
|
| 398 |
-
" global _sub_path\n",
|
| 399 |
-
" global _config_args\n",
|
| 400 |
-
" global _install_path\n",
|
| 401 |
-
" global _output_path\n",
|
| 402 |
-
" global _input_path\n",
|
| 403 |
-
" global _ui_dir_name\n",
|
| 404 |
-
" global freefrp_url\n",
|
| 405 |
-
" global ngrokTokenFile\n",
|
| 406 |
-
" global frpcSSLFFlies\n",
|
| 407 |
-
" global frpcExePath\n",
|
| 408 |
-
" global frpcStartArg\n",
|
| 409 |
-
" global otherArgs\n",
|
| 410 |
-
" global _setting_file\n",
|
| 411 |
-
" global _ui_config_file\n",
|
| 412 |
-
" global ngrokToken\n",
|
| 413 |
-
" global venvPath\n",
|
| 414 |
-
" \n",
|
| 415 |
-
" _useFrpc = locals().get('useFrpc') or globals().get('useFrpc') or True\n",
|
| 416 |
-
" _useNgrok = locals().get('useNgrok') or globals().get('useNgrok') or True\n",
|
| 417 |
-
" _reLoad = locals().get('reLoad') or globals().get('reLoad') or False\n",
|
| 418 |
-
" _before_downloading = locals().get('before_downloading') or globals().get('before_downloading') or ''\n",
|
| 419 |
-
" _async_downloading = locals().get('async_downloading') or globals().get('async_downloading') or ''\n",
|
| 420 |
-
" _before_start_sync_downloading = locals().get('before_start_sync_downloading') or globals().get('before_start_sync_downloading') or ''\n",
|
| 421 |
-
" _server_port = locals().get('server_port') or globals().get('server_port') or 7860\n",
|
| 422 |
-
" _sd_git_repo = locals().get('sd_git_repo') or globals().get('sd_git_repo') or 'https://github.com/viyiviyi/stable-diffusion-webui.git -b local' \n",
|
| 423 |
-
" _sd_git_repo = _sd_git_repo\\\n",
|
| 424 |
-
" .replace('{sdwui}','stable-diffusion-webui')\\\n",
|
| 425 |
-
" .replace('{wui}',\"webui\") \n",
|
| 426 |
-
" _sd_config_git_repu = locals().get('sd_config_git_repu') or globals().get('sd_config_git_repu') or 'https://github.com/viyiviyi/sd-configs.git'\n",
|
| 427 |
-
" _sd_config_git_repu = _sd_config_git_repu\\\n",
|
| 428 |
-
" .replace('{sdwui}','stable-diffusion-webui')\\\n",
|
| 429 |
-
" .replace('{wui}',\"webui\")\n",
|
| 430 |
-
" _huggingface_token = locals().get('huggingface_token') or globals().get('huggingface_token') or '{input_path}/configs/huggingface_token.txt'\n",
|
| 431 |
-
" _huggingface_token = _huggingface_token\\\n",
|
| 432 |
-
" .replace('{sdwui}','stable-diffusion-webui')\\\n",
|
| 433 |
-
" .replace('{wui}',\"webui\")\n",
|
| 434 |
-
" _huggingface_repo = locals().get('huggingface_repo') or globals().get('huggingface_repo') or ''\n",
|
| 435 |
-
" _huggingface_repo = _huggingface_repo\\\n",
|
| 436 |
-
" .replace('{sdwui}','stable-diffusion-webui')\\\n",
|
| 437 |
-
" .replace('{wui}',\"webui\")\n",
|
| 438 |
-
" _link_instead_of_copy = locals().get('link_instead_of_copy') or globals().get('link_instead_of_copy') or True\n",
|
| 439 |
-
" show_shell_info = locals().get('hidden_console_info') or globals().get('hidden_console_info')\n",
|
| 440 |
-
" if show_shell_info is None: show_shell_info = False\n",
|
| 441 |
-
" else: show_shell_info = not show_shell_info\n",
|
| 442 |
-
" _multi_case = locals().get('multi_case') or globals().get('multi_case') or False\n",
|
| 443 |
-
" _skip_start = locals().get('skip_start') or globals().get('skip_start') or True\n",
|
| 444 |
-
" _on_before_start = locals().get('on_before_start') or globals().get('on_before_start') or before_start \n",
|
| 445 |
-
" _skip_webui = locals().get('skip_webui') or globals().get('skip_webui') or False\n",
|
| 446 |
-
" _proxy_path = locals().get('proxy_path') or globals().get('proxy_path') or {}\n",
|
| 447 |
-
" _sub_path = locals().get('sub_path') or globals().get('sub_path') or ['/','/1/']\n",
|
| 448 |
-
" if len(_sub_path) != 2:\n",
|
| 449 |
-
" _sub_path = ['/','/1/']\n",
|
| 450 |
-
" \n",
|
| 451 |
-
" _config_args = locals().get('config_args') or globals().get('config_args') or {}\n",
|
| 452 |
-
" \n",
|
| 453 |
-
" _install_path = locals().get('install_path') or globals().get('install_path') or _install_path\n",
|
| 454 |
-
" _output_path = locals().get('output_path') or globals().get('output_path') or _output_path\n",
|
| 455 |
-
" _input_path = locals().get('input_path') or globals().get('input_path') or _input_path\n",
|
| 456 |
-
" _ui_dir_name = locals().get('ui_dir_name') or globals().get('ui_dir_name') or _ui_dir_name\n",
|
| 457 |
-
" \n",
|
| 458 |
-
" ngrokTokenFile = os.path.join(_input_path,'configs/ngrok_token.txt') # 非必填 存放ngrokToken的文件的路径\n",
|
| 459 |
-
" frpcConfigFile = os.path.join(_input_path,'configs/frpc_koishi.ini') # 非必填 frp 配置文件\n",
|
| 460 |
-
" # ss证书目录 下载nginx的版本,把pem格式改成crt格式\n",
|
| 461 |
-
" frpcSSLFFlies = [os.path.join(_input_path,'configs/koishi_ssl')]\n",
|
| 462 |
-
" if 'frp_ssl_dir' in locals() or 'frp_ssl_dir' in globals():\n",
|
| 463 |
-
" frpcSSLFFlies = frpcSSLFFlies + config_reader(locals().get('frp_ssl_dir') or globals().get('frp_ssl_dir'))\n",
|
| 464 |
-
" # frpc 文件目录 如果目录不存在,会自动下载,也可以在数据集搜索 viyiviyi/utils 添加\n",
|
| 465 |
-
" frpcExePath = replace_path(locals().get('frpc_exe_path') or globals().get('frpc_exe_path') or os.path.join(_input_path,'utils-tools/frpc_v0.51.0')) \n",
|
| 466 |
-
" # 其他需要加载的webui启动参数 写到【参数列表】这个配置\n",
|
| 467 |
-
" otherArgs = '--xformers'\n",
|
| 468 |
-
" if 'sd_start_args' in locals() or 'sd_start_args' in globals():\n",
|
| 469 |
-
" otherArgs = ' '.join([item for item in config_reader(locals().get('sd_start_args') or globals().get('sd_start_args')) if item != '--no-gradio-queue'])\n",
|
| 470 |
-
"\n",
|
| 471 |
-
" # 这下面的是用于初始化一些值或者环境变量的,轻易别改\n",
|
| 472 |
-
" _setting_file = replace_path(locals().get('setting_file') or globals().get('setting_file') or 'config.json')\n",
|
| 473 |
-
"\n",
|
| 474 |
-
" _ui_config_file = replace_path(locals().get('ui_config_file') or globals().get('ui_config_file') or 'ui-config.json')\n",
|
| 475 |
-
"\n",
|
| 476 |
-
" # 设置文件路径\n",
|
| 477 |
-
" if Path(f\"{os.environ['HOME']}/google_drive/MyDrive\").exists():\n",
|
| 478 |
-
" if _setting_file == '/kaggle/working/configs/config.json':\n",
|
| 479 |
-
" _setting_file = os.path.join(_output_path,'configs/config.json')\n",
|
| 480 |
-
" if _ui_config_file == '/kaggle/working/configs/ui-config.json':\n",
|
| 481 |
-
" _ui_config_file = os.path.join(_output_path,'configs/ui-config.json')\n",
|
| 482 |
-
"\n",
|
| 483 |
-
" frpcStartArg = load_frpc_config(replace_path(locals().get('frp_config_or_file') or globals().get('frp_config_or_file')) or '', _server_port)\n",
|
| 484 |
-
" if not frpcStartArg:\n",
|
| 485 |
-
" conf,url = get_freefrp_confog(_server_port)\n",
|
| 486 |
-
" echoToFile(conf,f'{_install_path}/configFiles/frpc_webui.ini')\n",
|
| 487 |
-
" freefrp_url = url\n",
|
| 488 |
-
" frpcStartArg = f' -c {_install_path}/configFiles/frpc_webui.ini'\n",
|
| 489 |
-
" ngrokToken=''\n",
|
| 490 |
-
" _ngrok_config_or_file = replace_path(locals().get('ngrok_config_or_file') or globals().get('ngrok_config_or_file')) or ngrokTokenFile\n",
|
| 491 |
-
" if _ngrok_config_or_file:\n",
|
| 492 |
-
" if Path(_ngrok_config_or_file.strip()).exists():\n",
|
| 493 |
-
" ngrokTokenFile = _ngrok_config_or_file.strip()\n",
|
| 494 |
-
" if Path(ngrokTokenFile).exists():\n",
|
| 495 |
-
" with open(ngrokTokenFile,encoding = \"utf-8\") as nkfile:\n",
|
| 496 |
-
" ngrokToken = nkfile.readline()\n",
|
| 497 |
-
" elif not _ngrok_config_or_file.strip().startswith('/'):\n",
|
| 498 |
-
" ngrokToken=_ngrok_config_or_file.strip()\n",
|
| 499 |
-
" \n",
|
| 500 |
-
" venvPath = os.path.join(_input_path,'sd-webui-venv-mini/venv.tar.bak') # 安装好的python环境 sd-webui-venv是一个公开是数据集 可以搜索添加\n",
|
| 501 |
-
" "
|
| 502 |
-
]
|
| 503 |
-
},
|
| 504 |
-
{
|
| 505 |
-
"cell_type": "markdown",
|
| 506 |
-
"metadata": {},
|
| 507 |
-
"source": [
|
| 508 |
-
"## 文件下载工具\n",
|
| 509 |
-
"\n",
|
| 510 |
-
"---\n",
|
| 511 |
-
"\n",
|
| 512 |
-
"link_or_download_flie(config:str, skip_url:bool=False, _link_instead_of_copy:bool=True, base_path:str = '',sync:bool=False,thread_num:int=None)"
|
| 513 |
-
]
|
| 514 |
-
},
|
| 515 |
-
{
|
| 516 |
-
"cell_type": "code",
|
| 517 |
-
"execution_count": null,
|
| 518 |
-
"metadata": {
|
| 519 |
-
"trusted": true
|
| 520 |
-
},
|
| 521 |
-
"outputs": [],
|
| 522 |
-
"source": [
|
| 523 |
-
"import concurrent.futures\n",
|
| 524 |
-
"import importlib\n",
|
| 525 |
-
"import os\n",
|
| 526 |
-
"import pprint\n",
|
| 527 |
-
"import re\n",
|
| 528 |
-
"import venv\n",
|
| 529 |
-
"from pathlib import Path\n",
|
| 530 |
-
"from typing import List\n",
|
| 531 |
-
"\n",
|
| 532 |
-
"import requests\n",
|
| 533 |
-
"\n",
|
| 534 |
-
"show_shell_info = False\n",
|
| 535 |
-
"\n",
|
| 536 |
-
"def is_installed(package):\n",
|
| 537 |
-
" try:\n",
|
| 538 |
-
" spec = importlib.util.find_spec(package)\n",
|
| 539 |
-
" except ModuleNotFoundError:\n",
|
| 540 |
-
" return False\n",
|
| 541 |
-
"\n",
|
| 542 |
-
" return spec is not None\n",
|
| 543 |
-
"\n",
|
| 544 |
-
"def download_file(url:str, filename:str, dist_path:str, cache_path = '',_link_instead_of_copy:bool=True,headers={}):\n",
|
| 545 |
-
" startTicks = time.time()\n",
|
| 546 |
-
" # 获取文���的真实文件名\n",
|
| 547 |
-
" if not filename:\n",
|
| 548 |
-
" with requests.get(url, stream=True,headers=headers) as r:\n",
|
| 549 |
-
" if 'Content-Disposition' in r.headers:\n",
|
| 550 |
-
" filename = r.headers['Content-Disposition'].split('filename=')[1].strip('\"')\n",
|
| 551 |
-
" r.close()\n",
|
| 552 |
-
" if not filename and re.search(r'/[^/]+\\.[^/]+$',url):\n",
|
| 553 |
-
" filename = url.split('/')[-1].split('?')[0]\n",
|
| 554 |
-
" \n",
|
| 555 |
-
" filename = re.sub(r'[\\\\/:*?\"<>|;]', '', filename)\n",
|
| 556 |
-
" filename = re.sub(r'[\\s\\t]+', '_', filename)\n",
|
| 557 |
-
" \n",
|
| 558 |
-
" print(f'下载 {filename} url: {url} --> {dist_path}')\n",
|
| 559 |
-
" \n",
|
| 560 |
-
" # 创建目录\n",
|
| 561 |
-
" if cache_path and not Path(cache_path).exists():\n",
|
| 562 |
-
" os.makedirs(cache_path,exist_ok=True)\n",
|
| 563 |
-
" if dist_path and not Path(dist_path).exists():\n",
|
| 564 |
-
" os.makedirs(dist_path,exist_ok=True)\n",
|
| 565 |
-
" \n",
|
| 566 |
-
" # 拼接文件的完整路径\n",
|
| 567 |
-
" filepath = os.path.join(dist_path, filename)\n",
|
| 568 |
-
"\n",
|
| 569 |
-
" if cache_path:\n",
|
| 570 |
-
" cache_path = os.path.join(cache_path, filename)\n",
|
| 571 |
-
" \n",
|
| 572 |
-
" # 判断文件是否已存在\n",
|
| 573 |
-
" if Path(filepath).exists():\n",
|
| 574 |
-
" print(f'文件 {filename} 已存在 {dist_path}')\n",
|
| 575 |
-
" return\n",
|
| 576 |
-
" \n",
|
| 577 |
-
" if cache_path and Path(cache_path).exists():\n",
|
| 578 |
-
" run(f'cp -n -r -f {\"-s\" if _link_instead_of_copy else \"\"} {cache_path} {dist_path}')\n",
|
| 579 |
-
" print(f'文件缓存 {cache_path} --> {dist_path}')\n",
|
| 580 |
-
" return\n",
|
| 581 |
-
" # 下载文件\n",
|
| 582 |
-
" size = 0\n",
|
| 583 |
-
" with requests.get(url, stream=True, headers=headers) as r:\n",
|
| 584 |
-
" r.raise_for_status()\n",
|
| 585 |
-
" with open(cache_path or filepath, 'wb') as f:\n",
|
| 586 |
-
" for chunk in r.iter_content(chunk_size=1024*1024):\n",
|
| 587 |
-
" if chunk:\n",
|
| 588 |
-
" size += len(chunk)\n",
|
| 589 |
-
" f.write(chunk)\n",
|
| 590 |
-
" # 如果使用了缓存目录 需要复制或链接文件到目标目录\n",
|
| 591 |
-
" if cache_path:\n",
|
| 592 |
-
" run(f'cp -n -r -f {\"-s\" if _link_instead_of_copy else \"\"} {cache_path} {dist_path}')\n",
|
| 593 |
-
" ticks = time.time()\n",
|
| 594 |
-
" print(f'下载完成 {filename} --> {dist_path} 大小{round(size/1024/1024,2)}M 耗时:{round(ticks - startTicks,2)}秒')\n",
|
| 595 |
-
" \n",
|
| 596 |
-
"def download_git(url, dist_path, cache_path = '',_link_instead_of_copy:bool=True):\n",
|
| 597 |
-
" if not Path(dist_path).exists():\n",
|
| 598 |
-
" os.makedirs(dist_path,exist_ok=True)\n",
|
| 599 |
-
" if show_shell_info:\n",
|
| 600 |
-
" print(f'git 下载 {url} --> {dist_path}')\n",
|
| 601 |
-
" if cache_path and not Path(cache_path).exists():\n",
|
| 602 |
-
" os.makedirs(cache_path,exist_ok=True)\n",
|
| 603 |
-
" run(f'git clone {url}',cwd = cache_path)\n",
|
| 604 |
-
" if cache_path:\n",
|
| 605 |
-
" run(f'cp -n -r -f {cache_path}/* {dist_path}')\n",
|
| 606 |
-
" else:\n",
|
| 607 |
-
" run(f'git clone {url}',cwd = dist_path)\n",
|
| 608 |
-
" if show_shell_info:\n",
|
| 609 |
-
" print(f'git 下载完成 {url} --> {dist_path}')\n",
|
| 610 |
-
" \n",
|
| 611 |
-
" \n",
|
| 612 |
-
"def download_huggingface(url:str, filename:str, dist_path, cache_path = '',_link_instead_of_copy:bool=True):\n",
|
| 613 |
-
" fileReg = r'^https:\\/\\/huggingface.co(\\/([^\\/]+\\/)?[^\\/]+\\/[^\\/]+\\/(resolve|blob)\\/[^\\/]+\\/|[^\\.]+\\.[^\\.]+$|download=true)'\n",
|
| 614 |
-
" def isFile(url:str):\n",
|
| 615 |
-
" if re.match(fileReg,url):\n",
|
| 616 |
-
" return True\n",
|
| 617 |
-
" return False\n",
|
| 618 |
-
" if isFile(url):\n",
|
| 619 |
-
" download_file(url,filename,dist_path,cache_path,_link_instead_of_copy,headers=huggingface_headers)\n",
|
| 620 |
-
" else:\n",
|
| 621 |
-
" download_git(url,dist_path,cache_path,_link_instead_of_copy)\n",
|
| 622 |
-
" \n",
|
| 623 |
-
"# 加入文件到下载列表\n",
|
| 624 |
-
"def pause_url(url:str,dist_path:str):\n",
|
| 625 |
-
" file_name = ''\n",
|
| 626 |
-
" if re.match(r'^[^:]+:(https?|ftps?)://', url, flags=0):\n",
|
| 627 |
-
" file_name = re.findall(r'^[^:]+:',url)[0][:-1]\n",
|
| 628 |
-
" url = url[len(file_name)+1:]\n",
|
| 629 |
-
" if not re.match(r'^(https?|ftps?)://',url):\n",
|
| 630 |
-
" return\n",
|
| 631 |
-
" file_name = re.sub(r'\\s+','_',file_name or '')\n",
|
| 632 |
-
" path_hash = str(hash(url)).replace('-','')\n",
|
| 633 |
-
" \n",
|
| 634 |
-
" return {'file_name':file_name,'path_hash':path_hash,'url':url,'dist_path':dist_path}\n",
|
| 635 |
-
"\n",
|
| 636 |
-
"def download_urls(download_list:List[dict],sync:bool=False,thread_num:int=5, \n",
|
| 637 |
-
" cache_path:str=os.path.join(os.environ['HOME'],'.cache','download_util'),\n",
|
| 638 |
-
" _link_instead_of_copy:bool=True,is_await:bool=False):\n",
|
| 639 |
-
" if sync:\n",
|
| 640 |
-
" for conf in download_list:\n",
|
| 641 |
-
" cache_dir = os.path.join(cache_path,conf['path_hash'])\n",
|
| 642 |
-
" if conf['url'].startswith('https://github.com'):\n",
|
| 643 |
-
" try:\n",
|
| 644 |
-
" download_git(conf['url'],conf['dist_path'],cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy)\n",
|
| 645 |
-
" except:\n",
|
| 646 |
-
" pass\n",
|
| 647 |
-
" continue\n",
|
| 648 |
-
" if conf['url'].startswith('https://huggingface.co'):\n",
|
| 649 |
-
" try:\n",
|
| 650 |
-
" download_huggingface(conf['url'],conf['file_name'],conf['dist_path'],cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy)\n",
|
| 651 |
-
" except:\n",
|
| 652 |
-
" pass\n",
|
| 653 |
-
" continue\n",
|
| 654 |
-
" if conf['url'].startswith('https://civitai.com'):\n",
|
| 655 |
-
" if not re.search(r'token=.+', conf['url']):\n",
|
| 656 |
-
" if conf['url'].find('?') == -1:\n",
|
| 657 |
-
" conf['url'] = conf['url']+'?token=fee8bb78b75566eddfd04d061996185c'\n",
|
| 658 |
-
" else:\n",
|
| 659 |
-
" conf['url'] = conf['url']+'&token=fee8bb78b75566eddfd04d061996185c'\n",
|
| 660 |
-
" try:\n",
|
| 661 |
-
" download_file(conf['url'],conf['file_name'],conf['dist_path'],cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy)\n",
|
| 662 |
-
" except:\n",
|
| 663 |
-
" pass\n",
|
| 664 |
-
" else:\n",
|
| 665 |
-
" executor = concurrent.futures.ThreadPoolExecutor(max_workers=thread_num)\n",
|
| 666 |
-
" futures = []\n",
|
| 667 |
-
" for conf in download_list:\n",
|
| 668 |
-
" cache_dir = os.path.join(cache_path,conf['path_hash'])\n",
|
| 669 |
-
" if conf['url'].startswith('https://github.com'):\n",
|
| 670 |
-
" futures.append(executor.submit(download_git, conf['url'],conf['dist_path'],\n",
|
| 671 |
-
" cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy))\n",
|
| 672 |
-
" continue\n",
|
| 673 |
-
" if conf['url'].startswith('https://huggingface.co'):\n",
|
| 674 |
-
" futures.append(executor.submit(download_huggingface,conf['url'],conf['file_name'],conf['dist_path'],cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy))\n",
|
| 675 |
-
" continue\n",
|
| 676 |
-
" if conf['url'].startswith('https://civitai.com'):\n",
|
| 677 |
-
" if not re.search(r'token=.+', conf['url']):\n",
|
| 678 |
-
" if conf['url'].find('?') == -1:\n",
|
| 679 |
-
" conf['url'] = conf['url']+'?token=fee8bb78b75566eddfd04d061996185c'\n",
|
| 680 |
-
" else:\n",
|
| 681 |
-
" conf['url'] = conf['url']+'&token=fee8bb78b75566eddfd04d061996185c'\n",
|
| 682 |
-
" futures.append(executor.submit(download_file, conf['url'],conf['file_name'],conf['dist_path'],\n",
|
| 683 |
-
" cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy))\n",
|
| 684 |
-
" if is_await:\n",
|
| 685 |
-
" concurrent.futures.wait(futures)\n",
|
| 686 |
-
" \n",
|
| 687 |
-
" \n",
|
| 688 |
-
"def parse_config(config:str):\n",
|
| 689 |
-
" space_string = ' \\n\\r\\t\\'\\\",'\n",
|
| 690 |
-
" other_flie_list = [item.split('#')[0].strip(space_string) for item in config.split('\\n') if item.strip(space_string)]\n",
|
| 691 |
-
" other_flie_list = [item.strip() for item in other_flie_list if item.strip()]\n",
|
| 692 |
-
" other_flie_list_store = {}\n",
|
| 693 |
-
" other_flie_list_store_name='default'\n",
|
| 694 |
-
" other_flie_list_store_list_cache=[]\n",
|
| 695 |
-
" \n",
|
| 696 |
-
" for item in other_flie_list:\n",
|
| 697 |
-
" if item.startswith('[') and item.endswith(']'):\n",
|
| 698 |
-
" if not other_flie_list_store_name == 'default':\n",
|
| 699 |
-
" other_flie_list_store[other_flie_list_store_name]=other_flie_list_store_list_cache\n",
|
| 700 |
-
" other_flie_list_store_list_cache = []\n",
|
| 701 |
-
" other_flie_list_store_name = item[1:-1]\n",
|
| 702 |
-
" else:\n",
|
| 703 |
-
" other_flie_list_store_list_cache.append(item)\n",
|
| 704 |
-
" other_flie_list_store[other_flie_list_store_name]=other_flie_list_store_list_cache\n",
|
| 705 |
-
" \n",
|
| 706 |
-
" return other_flie_list_store\n",
|
| 707 |
-
"\n",
|
| 708 |
-
"\n",
|
| 709 |
-
"def link_or_download_flie(config:str, skip_url:bool=False, _link_instead_of_copy:bool=True, base_path:str = '',\n",
|
| 710 |
-
" sync:bool=False,thread_num:int=None, is_await:bool=False):\n",
|
| 711 |
-
" store:dict[str,List[str]] = parse_config(config)\n",
|
| 712 |
-
" download_list = []\n",
|
| 713 |
-
" for dist_dir in store.keys():\n",
|
| 714 |
-
" dist_path = os.path.join(base_path,dist_dir)\n",
|
| 715 |
-
" os.makedirs(dist_path,exist_ok=True)\n",
|
| 716 |
-
" for path in store[dist_dir]:\n",
|
| 717 |
-
" if 'https://' in path or 'http://' in path:\n",
|
| 718 |
-
" if skip_url:\n",
|
| 719 |
-
" continue\n",
|
| 720 |
-
" if sync:\n",
|
| 721 |
-
" try:\n",
|
| 722 |
-
" download_urls([pause_url(path,dist_path)],_link_instead_of_copy = _link_instead_of_copy, sync=sync)\n",
|
| 723 |
-
" except:\n",
|
| 724 |
-
" pass\n",
|
| 725 |
-
" continue\n",
|
| 726 |
-
" download_list.append(pause_url(path,dist_path))\n",
|
| 727 |
-
" else:\n",
|
| 728 |
-
" run(f'cp -n -r -f {\"-s\" if _link_instead_of_copy else \"\"} {path} {dist_path}')\n",
|
| 729 |
-
" if show_shell_info:\n",
|
| 730 |
-
" print(f'{\"链接\" if _link_instead_of_copy else \"复制\"} {path} --> {dist_path}')\n",
|
| 731 |
-
" run(f'rm -f {dist_path}/\\*.* ')\n",
|
| 732 |
-
" if not skip_url:\n",
|
| 733 |
-
" if show_shell_info:\n",
|
| 734 |
-
" pprint.pprint(download_list)\n",
|
| 735 |
-
" try:\n",
|
| 736 |
-
" download_urls(download_list,_link_instead_of_copy = _link_instead_of_copy, sync=sync, thread_num=thread_num or 3,is_await=is_await)\n",
|
| 737 |
-
" except:\n",
|
| 738 |
-
" pass"
|
| 739 |
-
]
|
| 740 |
-
},
|
| 741 |
-
{
|
| 742 |
-
"cell_type": "markdown",
|
| 743 |
-
"metadata": {
|
| 744 |
-
"id": "p0uS-BLULCtD"
|
| 745 |
-
},
|
| 746 |
-
"source": [
|
| 747 |
-
"## kaggle public API\n",
|
| 748 |
-
"\n",
|
| 749 |
-
"**不能使用%cd这种会改变当前工作目录的命令,会导致和其他线程冲突**\n",
|
| 750 |
-
"\n",
|
| 751 |
-
"---"
|
| 752 |
-
]
|
| 753 |
-
},
|
| 754 |
-
{
|
| 755 |
-
"cell_type": "code",
|
| 756 |
-
"execution_count": null,
|
| 757 |
-
"metadata": {
|
| 758 |
-
"_kg_hide-input": true,
|
| 759 |
-
"id": "m8FJi4j0LCtD",
|
| 760 |
-
"trusted": true
|
| 761 |
-
},
|
| 762 |
-
"outputs": [],
|
| 763 |
-
"source": [
|
| 764 |
-
"# 安装kaggle的api token文件\n",
|
| 765 |
-
"def initKaggleConfig():\n",
|
| 766 |
-
" if Path('~/.kaggle/kaggle.json').exists():\n",
|
| 767 |
-
" return True\n",
|
| 768 |
-
" if Path(kaggleApiTokenFile).exists():\n",
|
| 769 |
-
" run(f'''mkdir -p ~/.kaggle/''')\n",
|
| 770 |
-
" run('cp '+kaggleApiTokenFile+' ~/.kaggle/kaggle.json')\n",
|
| 771 |
-
" run(f'''chmod 600 ~/.kaggle/kaggle.json''')\n",
|
| 772 |
-
" return True\n",
|
| 773 |
-
" print('缺少kaggle的apiToken文件,访问:https://www.kaggle.com/你的kaggle用户名/account 获取')\n",
|
| 774 |
-
" return False\n",
|
| 775 |
-
"\n",
|
| 776 |
-
"def getUserName():\n",
|
| 777 |
-
" if not initKaggleConfig(): return\n",
|
| 778 |
-
" import kaggle\n",
|
| 779 |
-
" return kaggle.KaggleApi().read_config_file()['username']\n",
|
| 780 |
-
"\n",
|
| 781 |
-
"def createOrUpdateDataSet(path:str,datasetName:str):\n",
|
| 782 |
-
" if not initKaggleConfig(): return\n",
|
| 783 |
-
" print('创建或更新数据集 '+datasetName)\n",
|
| 784 |
-
" import kaggle\n",
|
| 785 |
-
" run(f'mkdir -p {_install_path}/kaggle_cache')\n",
|
| 786 |
-
" run(f'rm -rf {_install_path}/kaggle_cache/*')\n",
|
| 787 |
-
" datasetDirPath = _install_path+'/kaggle_cache/'+datasetName\n",
|
| 788 |
-
" run('mkdir -p '+datasetDirPath)\n",
|
| 789 |
-
" run('cp -f '+path+' '+datasetDirPath+'/')\n",
|
| 790 |
-
" username = getUserName()\n",
|
| 791 |
-
" print(\"kaggle username:\"+username)\n",
|
| 792 |
-
" datasetPath = username+'/'+datasetName\n",
|
| 793 |
-
" datasetList = kaggle.api.dataset_list(mine=True,search=datasetPath)\n",
|
| 794 |
-
" print(datasetList)\n",
|
| 795 |
-
" if len(datasetList) == 0 or datasetPath not in [str(d) for d in datasetList]: # 创建 create\n",
|
| 796 |
-
" run('kaggle datasets init -p' + datasetDirPath)\n",
|
| 797 |
-
" metadataFile = datasetDirPath+'/dataset-metadata.json'\n",
|
| 798 |
-
" run('sed -i s/INSERT_TITLE_HERE/'+ datasetName + '/g ' + metadataFile)\n",
|
| 799 |
-
" run('sed -i s/INSERT_SLUG_HERE/'+ datasetName + '/g ' + metadataFile)\n",
|
| 800 |
-
" run('cat '+metadataFile)\n",
|
| 801 |
-
" run('kaggle datasets create -p '+datasetDirPath)\n",
|
| 802 |
-
" print('create database done')\n",
|
| 803 |
-
" else:\n",
|
| 804 |
-
" kaggle.api.dataset_metadata(datasetPath,datasetDirPath)\n",
|
| 805 |
-
" kaggle.api.dataset_create_version(datasetDirPath, 'auto update',dir_mode='zip')\n",
|
| 806 |
-
" print('upload database done')\n",
|
| 807 |
-
"\n",
|
| 808 |
-
"def downloadDatasetFiles(datasetName:str,outputPath:str):\n",
|
| 809 |
-
" if not initKaggleConfig(): return\n",
|
| 810 |
-
" print('下载数据集文件 '+datasetName)\n",
|
| 811 |
-
" import kaggle\n",
|
| 812 |
-
" username = getUserName()\n",
|
| 813 |
-
" datasetPath = username+'/'+datasetName\n",
|
| 814 |
-
" datasetList = kaggle.api.dataset_list(mine=True,search=datasetPath)\n",
|
| 815 |
-
" if datasetPath not in [str(d) for d in datasetList]:\n",
|
| 816 |
-
" return False\n",
|
| 817 |
-
" run('mkdir -p '+outputPath)\n",
|
| 818 |
-
" kaggle.api.dataset_download_files(datasetPath,path=outputPath,unzip=True)\n",
|
| 819 |
-
" return True\n",
|
| 820 |
-
"\n"
|
| 821 |
-
]
|
| 822 |
-
},
|
| 823 |
-
{
|
| 824 |
-
"cell_type": "markdown",
|
| 825 |
-
"metadata": {},
|
| 826 |
-
"source": [
|
| 827 |
-
"## 同步文件夹到 huggingface\n",
|
| 828 |
-
"\n",
|
| 829 |
-
"---"
|
| 830 |
-
]
|
| 831 |
-
},
|
| 832 |
-
{
|
| 833 |
-
"cell_type": "code",
|
| 834 |
-
"execution_count": null,
|
| 835 |
-
"metadata": {
|
| 836 |
-
"trusted": true
|
| 837 |
-
},
|
| 838 |
-
"outputs": [],
|
| 839 |
-
"source": [
|
| 840 |
-
"# 文件夹与 huggingface 同步\n",
|
| 841 |
-
"if _huggingface_token and _huggingface_repo:\n",
|
| 842 |
-
" if not is_installed('watchdog'):\n",
|
| 843 |
-
" requirements.append('watchdog')\n",
|
| 844 |
-
" if not is_installed('huggingface_hub'):\n",
|
| 845 |
-
" requirements.append('huggingface_hub')\n",
|
| 846 |
-
" else:\n",
|
| 847 |
-
" try:\n",
|
| 848 |
-
" from huggingface_hub import HfApi,login,snapshot_download\n",
|
| 849 |
-
" except:\n",
|
| 850 |
-
" requirements.append('huggingface_hub')\n",
|
| 851 |
-
"\n",
|
| 852 |
-
"huggingface_is_init = False\n",
|
| 853 |
-
"\n",
|
| 854 |
-
"def init_huggingface():\n",
|
| 855 |
-
" if not _huggingface_token:\n",
|
| 856 |
-
" return False\n",
|
| 857 |
-
"\n",
|
| 858 |
-
" global huggingface_headers\n",
|
| 859 |
-
" global huggingface_is_init\n",
|
| 860 |
-
" \n",
|
| 861 |
-
" from huggingface_hub import login\n",
|
| 862 |
-
" token = replace_path(_huggingface_token)\n",
|
| 863 |
-
" if not _huggingface_token.startswith('hf_') and Path(token).exists():\n",
|
| 864 |
-
" with open(token,encoding = \"utf-8\") as nkfile:\n",
|
| 865 |
-
" token = nkfile.readline()\n",
|
| 866 |
-
" if not token.startswith('hf_'):\n",
|
| 867 |
-
" print('huggingface token 不正确,请将 token 或 仅存放token 的txt文件路径填入 _huggingface_token 配置')\n",
|
| 868 |
-
" return False\n",
|
| 869 |
-
" login(token,add_to_git_credential=True)\n",
|
| 870 |
-
" huggingface_headers = {'Authorization': 'Bearer '+token}\n",
|
| 871 |
-
" print('huggingface token 已经加载,可以下载私有仓库或文件')\n",
|
| 872 |
-
" \n",
|
| 873 |
-
" if not _huggingface_repo:\n",
|
| 874 |
-
" print('huggingface 同步收藏图片功能不会启动,可增加配置项 huggingface_token = \"token\" 和 huggingface_repo = “仓库id” 后启用 huggingface 同步收藏图片功能')\n",
|
| 875 |
-
" return False\n",
|
| 876 |
-
" huggingface_is_init = True\n",
|
| 877 |
-
" return True\n",
|
| 878 |
-
"\n",
|
| 879 |
-
"\n",
|
| 880 |
-
"def download__huggingface_repo(repo_id:str,dist_directory:str=None,repo_type='dataset',callback=None):\n",
|
| 881 |
-
" if not huggingface_is_init:\n",
|
| 882 |
-
" print('huggingface 相关功能未初始化 请调用 init_huggingface() 初始化')\n",
|
| 883 |
-
" \n",
|
| 884 |
-
" if not dist_directory:\n",
|
| 885 |
-
" dist_directory = f'{_install_path}/{_ui_dir_name}/log'\n",
|
| 886 |
-
" \n",
|
| 887 |
-
" print('下载收藏的图片')\n",
|
| 888 |
-
" if not Path(f'{_install_path}/cache/huggingface/huggingface_repo').exists():\n",
|
| 889 |
-
" mkdirs(f'{_install_path}/cache/huggingface')\n",
|
| 890 |
-
" repo_path = ''\n",
|
| 891 |
-
" if repo_type == 'dataset':\n",
|
| 892 |
-
" repo_path = 'datasets'\n",
|
| 893 |
-
" if repo_type == 'space':\n",
|
| 894 |
-
" repo_path = 'spaces'\n",
|
| 895 |
-
" if repo_path:\n",
|
| 896 |
-
" run(f'git clone https://huggingface.co/{repo_path}/{repo_id} huggingface_repo',cwd=f'{_install_path}/cache/huggingface')\n",
|
| 897 |
-
" else:\n",
|
| 898 |
-
" run(f'git clone https://huggingface.co/{repo_id} huggingface_repo',cwd=f'{_install_path}/cache/huggingface')\n",
|
| 899 |
-
" if Path(f'{_install_path}/cache/huggingface/huggingface_repo').exists():\n",
|
| 900 |
-
" run(f'cp -r -f -n -s {_install_path}/cache/huggingface/huggingface_repo/* {dist_directory}')\n",
|
| 901 |
-
" if callback:\n",
|
| 902 |
-
" callback()\n",
|
| 903 |
-
"\n",
|
| 904 |
-
"def start_sync_log_to_huggingface(repo_id:str,directory_to_watch:str=None,repo_type='dataset'):\n",
|
| 905 |
-
" if not huggingface_is_init:\n",
|
| 906 |
-
" print('huggingface 相关功能未初始化 请调用 init_huggingface() 初始化')\n",
|
| 907 |
-
" \n",
|
| 908 |
-
" from watchdog.observers import Observer\n",
|
| 909 |
-
" from watchdog.events import FileSystemEventHandler\n",
|
| 910 |
-
" from huggingface_hub import HfApi,login,snapshot_download\n",
|
| 911 |
-
" \n",
|
| 912 |
-
" # 配置监视的目录和 Hugging Face 仓库信息\n",
|
| 913 |
-
" class FileChangeHandler(FileSystemEventHandler):\n",
|
| 914 |
-
" def __init__(self, api, repo_id, repo_type,directory_to_watch):\n",
|
| 915 |
-
" self.api = api\n",
|
| 916 |
-
" self.repo_id = repo_id\n",
|
| 917 |
-
" self.repo_type = repo_type\n",
|
| 918 |
-
" self.directory_to_watch = directory_to_watch\n",
|
| 919 |
-
" def on_created(self, event):\n",
|
| 920 |
-
" if not event.is_directory:\n",
|
| 921 |
-
" # 上传新文件到 Hugging Face 仓库\n",
|
| 922 |
-
" file_path = event.src_path\n",
|
| 923 |
-
" file_name:str = os.path.basename(file_path)\n",
|
| 924 |
-
" print(file_name)\n",
|
| 925 |
-
" if file_name[file_name.rindex('.'):] not in ['.png','.jpg','.txt','.webp','.jpeg']: return\n",
|
| 926 |
-
" print(file_name,'>>','huggingface')\n",
|
| 927 |
-
" try:\n",
|
| 928 |
-
" self.api.upload_file(\n",
|
| 929 |
-
" path_or_fileobj=file_path,\n",
|
| 930 |
-
" path_in_repo=file_path.replace(self.directory_to_watch,''),\n",
|
| 931 |
-
" repo_id=self.repo_id,\n",
|
| 932 |
-
" repo_type=self.repo_type,\n",
|
| 933 |
-
" )\n",
|
| 934 |
-
" except IOError as error:\n",
|
| 935 |
-
" print(error)\n",
|
| 936 |
-
"\n",
|
| 937 |
-
" def on_deleted(self, event):\n",
|
| 938 |
-
" if not event.is_directory:\n",
|
| 939 |
-
" # 从 Hugging Face 仓库删除文件\n",
|
| 940 |
-
" file_path = event.src_path\n",
|
| 941 |
-
" file_name = os.path.basename(file_path)\n",
|
| 942 |
-
" if file_name[file_name.rindex('.'):] not in ['.png','.jpg','.txt','.webp','.jpeg']: return\n",
|
| 943 |
-
" try:\n",
|
| 944 |
-
" self.api.delete_file(\n",
|
| 945 |
-
" path_in_repo=file_path.replace(self.directory_to_watch,''),\n",
|
| 946 |
-
" repo_id=self.repo_id,\n",
|
| 947 |
-
" repo_type=self.repo_type,\n",
|
| 948 |
-
" )\n",
|
| 949 |
-
" except IOError as error:\n",
|
| 950 |
-
" print(error)\n",
|
| 951 |
-
"\n",
|
| 952 |
-
" def on_modified(self, event):\n",
|
| 953 |
-
" if not event.is_directory:\n",
|
| 954 |
-
" # 更新 Hugging Face 仓库中的文件\n",
|
| 955 |
-
" file_path = event.src_path\n",
|
| 956 |
-
" file_name = os.path.basename(file_path)\n",
|
| 957 |
-
" if file_name[file_name.rindex('.'):] not in ['.png','.jpg','.txt','.webp','.jpeg']: return\n",
|
| 958 |
-
" try:\n",
|
| 959 |
-
" self.api.upload_file(\n",
|
| 960 |
-
" path_or_fileobj=file_path,\n",
|
| 961 |
-
" path_in_repo=file_path.replace(self.directory_to_watch,''),\n",
|
| 962 |
-
" repo_id=self.repo_id,\n",
|
| 963 |
-
" repo_type=self.repo_type,\n",
|
| 964 |
-
" )\n",
|
| 965 |
-
" except IOError as error:\n",
|
| 966 |
-
" print(error)\n",
|
| 967 |
-
"\n",
|
| 968 |
-
" def on_moved(self, event):\n",
|
| 969 |
-
" if not event.is_directory:\n",
|
| 970 |
-
" file_path = event.dest_path\n",
|
| 971 |
-
" file_name = os.path.basename(file_path)\n",
|
| 972 |
-
" if file_name[file_name.rindex('.'):] not in ['.png','.jpg','.txt','.webp','.jpeg']: return\n",
|
| 973 |
-
" if event.dest_path.startswith(self.directory_to_watch):\n",
|
| 974 |
-
" try:\n",
|
| 975 |
-
" self.api.upload_file(\n",
|
| 976 |
-
" path_or_fileobj=file_path,\n",
|
| 977 |
-
" path_in_repo=file_path.replace(self.directory_to_watch,''),\n",
|
| 978 |
-
" repo_id=self.repo_id,\n",
|
| 979 |
-
" repo_type=self.repo_type,\n",
|
| 980 |
-
" )\n",
|
| 981 |
-
" except IOError as error:\n",
|
| 982 |
-
" print(error)\n",
|
| 983 |
-
"\n",
|
| 984 |
-
" api = HfApi()\n",
|
| 985 |
-
" \n",
|
| 986 |
-
" if not directory_to_watch:\n",
|
| 987 |
-
" directory_to_watch = f'{_install_path}/{_ui_dir_name}/log'\n",
|
| 988 |
-
" # 创建观察者对象并注册文件变化处理程序\n",
|
| 989 |
-
" event_handler = FileChangeHandler(api,repo_id,repo_type,directory_to_watch)\n",
|
| 990 |
-
" observer = Observer()\n",
|
| 991 |
-
" observer.schedule(event_handler, directory_to_watch, recursive=True)\n",
|
| 992 |
-
"\n",
|
| 993 |
-
" # 启动观察者\n",
|
| 994 |
-
" observer.name = \"solo_directory_to_watch\"\n",
|
| 995 |
-
" print(f'启动收藏图片文件夹监听,并自动同步到 huggingface {repo_type} : {repo_id}')\n",
|
| 996 |
-
" observer.start()"
|
| 997 |
-
]
|
| 998 |
-
},
|
| 999 |
-
{
|
| 1000 |
-
"cell_type": "markdown",
|
| 1001 |
-
"metadata": {
|
| 1002 |
-
"id": "sswa04veLCtE"
|
| 1003 |
-
},
|
| 1004 |
-
"source": [
|
| 1005 |
-
"## 工具函数\n",
|
| 1006 |
-
"**不能使用%cd这种会改变当前工作目录的命令,会导致和其他线程冲突**\n",
|
| 1007 |
-
"\n",
|
| 1008 |
-
"---"
|
| 1009 |
-
]
|
| 1010 |
-
},
|
| 1011 |
-
{
|
| 1012 |
-
"cell_type": "code",
|
| 1013 |
-
"execution_count": null,
|
| 1014 |
-
"metadata": {
|
| 1015 |
-
"_kg_hide-input": true,
|
| 1016 |
-
"trusted": true
|
| 1017 |
-
},
|
| 1018 |
-
"outputs": [],
|
| 1019 |
-
"source": [
|
| 1020 |
-
"\n",
|
| 1021 |
-
"def zipPath(path:str,zipName:str,format='tar'):\n",
|
| 1022 |
-
" if path.startswith('$install_path'):\n",
|
| 1023 |
-
" path = path.replace('$install_path',_install_path)\n",
|
| 1024 |
-
" if path.startswith('$output_path'):\n",
|
| 1025 |
-
" path = path.replace('$install_path',_output_path)\n",
|
| 1026 |
-
" if not path.startswith('/'):\n",
|
| 1027 |
-
" path = f'{_install_path}/{_ui_dir_name}/{path}'\n",
|
| 1028 |
-
" if Path(path).exists():\n",
|
| 1029 |
-
" if 'tar' == format:\n",
|
| 1030 |
-
" run(f'tar -cf {_output_path}/'+ zipName +'.tar -C '+ path +' . ')\n",
|
| 1031 |
-
" elif 'gz' == format:\n",
|
| 1032 |
-
" run(f'tar -czf {_output_path}/'+ zipName +'.tar.gz -C '+ path +' . ')\n",
|
| 1033 |
-
" return\n",
|
| 1034 |
-
" print('指定的目录不存在:'+path)\n",
|
| 1035 |
-
" \n",
|
| 1036 |
-
"def get_folder_list(directory:str): \n",
|
| 1037 |
-
" folder_list = [] \n",
|
| 1038 |
-
" for item in os.listdir(directory): \n",
|
| 1039 |
-
" if os.path.isdir(os.path.join(directory, item)): \n",
|
| 1040 |
-
" folder_list.append(item) \n",
|
| 1041 |
-
" return folder_list\n",
|
| 1042 |
-
"\n",
|
| 1043 |
-
"def read_text_file(file_path:str):\n",
|
| 1044 |
-
" if not Path(file_path).exists(): return ''\n",
|
| 1045 |
-
" with open(file_path,\"r\") as f:\n",
|
| 1046 |
-
" text = file.read()\n",
|
| 1047 |
-
" if text: return text.strip()\n",
|
| 1048 |
-
" return ''"
|
| 1049 |
-
]
|
| 1050 |
-
},
|
| 1051 |
-
{
|
| 1052 |
-
"cell_type": "markdown",
|
| 1053 |
-
"metadata": {},
|
| 1054 |
-
"source": [
|
| 1055 |
-
"## 内网穿透\n",
|
| 1056 |
-
"\n",
|
| 1057 |
-
"---"
|
| 1058 |
-
]
|
| 1059 |
-
},
|
| 1060 |
-
{
|
| 1061 |
-
"cell_type": "code",
|
| 1062 |
-
"execution_count": null,
|
| 1063 |
-
"metadata": {
|
| 1064 |
-
"_kg_hide-input": true,
|
| 1065 |
-
"_kg_hide-output": true,
|
| 1066 |
-
"id": "coqQvTSLLCtE",
|
| 1067 |
-
"trusted": true
|
| 1068 |
-
},
|
| 1069 |
-
"outputs": [],
|
| 1070 |
-
"source": [
|
| 1071 |
-
"def printUrl(url,name=''):\n",
|
| 1072 |
-
" print(f'{name} 访问地址:{url}')\n",
|
| 1073 |
-
" for key in sorted(_proxy_path.keys(), key=len)[::-1]:\n",
|
| 1074 |
-
" print(f'{name} 本地服务:{_proxy_path[key]} 访问地址:{url}{key}')\n",
|
| 1075 |
-
"# ngrok\n",
|
| 1076 |
-
"def startNgrok(ngrokToken:str,ngrokLocalPort:int):\n",
|
| 1077 |
-
" if not is_installed('pyngrok'):\n",
|
| 1078 |
-
" run('pip install pyngrok')\n",
|
| 1079 |
-
" from pyngrok import conf, ngrok\n",
|
| 1080 |
-
" try:\n",
|
| 1081 |
-
" conf.get_default().auth_token = ngrokToken\n",
|
| 1082 |
-
" conf.get_default().monitor_thread = False\n",
|
| 1083 |
-
" ssh_tunnels = ngrok.get_tunnels(conf.get_default())\n",
|
| 1084 |
-
" url = ''\n",
|
| 1085 |
-
" if len(ssh_tunnels) == 0:\n",
|
| 1086 |
-
" ssh_tunnel = ngrok.connect(ngrokLocalPort)\n",
|
| 1087 |
-
" url = ssh_tunnel.public_url\n",
|
| 1088 |
-
" print('ngrok 访问地址:'+ssh_tunnel.public_url)\n",
|
| 1089 |
-
" else:\n",
|
| 1090 |
-
" print('ngrok 访问地址:'+ssh_tunnels[0].public_url)\n",
|
| 1091 |
-
" url = ssh_tunnels[0].public_url\n",
|
| 1092 |
-
" printUrl(url,'ngrok')\n",
|
| 1093 |
-
" def auto_request_ngrok():\n",
|
| 1094 |
-
" if url:\n",
|
| 1095 |
-
" while(_runing):\n",
|
| 1096 |
-
" time.sleep(60*1)\n",
|
| 1097 |
-
" try:\n",
|
| 1098 |
-
" res = requests.get(url+'/',headers={\"ngrok-skip-browser-warning\" : \"1\"},timeout=10)\n",
|
| 1099 |
-
" except:\n",
|
| 1100 |
-
" ''\n",
|
| 1101 |
-
" # print('自动调用ngrok链接以保存链接不会断开',res.status_code)\n",
|
| 1102 |
-
"\n",
|
| 1103 |
-
" # threading.Thread(target = auto_request_ngrok,daemon=True,name='solo_auto_request_ngrok').start()\n",
|
| 1104 |
-
" except:\n",
|
| 1105 |
-
" print('启动ngrok出错')\n",
|
| 1106 |
-
" \n",
|
| 1107 |
-
"def startFrpc(name,configFile):\n",
|
| 1108 |
-
" if not Path(f'{_install_path}/frpc/frpc').exists():\n",
|
| 1109 |
-
" installFrpExe()\n",
|
| 1110 |
-
" if freefrp_url:\n",
|
| 1111 |
-
" printUrl(freefrp_url,'freefrp')\n",
|
| 1112 |
-
" echoToFile(f'''\n",
|
| 1113 |
-
"cd {_install_path}/frpc/\n",
|
| 1114 |
-
"{_install_path}/frpc/frpc {configFile}\n",
|
| 1115 |
-
"''',f'{_install_path}/frpc/start.sh')\n",
|
| 1116 |
-
" get_ipython().system(f'''bash {_install_path}/frpc/start.sh''')\n",
|
| 1117 |
-
" \n",
|
| 1118 |
-
"def installFrpExe():\n",
|
| 1119 |
-
" if _useFrpc:\n",
|
| 1120 |
-
" print('安装frpc')\n",
|
| 1121 |
-
" run(f'mkdir -p {_install_path}/frpc')\n",
|
| 1122 |
-
" if Path(frpcExePath).exists():\n",
|
| 1123 |
-
" run(f'cp -f -n {frpcExePath} {_install_path}/frpc/frpc')\n",
|
| 1124 |
-
" else:\n",
|
| 1125 |
-
" run(f'wget \"https://huggingface.co/datasets/ACCA225/Frp/resolve/main/frpc\" -O {_install_path}/frpc/frpc')\n",
|
| 1126 |
-
" \n",
|
| 1127 |
-
" for ssl in frpcSSLFFlies:\n",
|
| 1128 |
-
" if Path(ssl).exists():\n",
|
| 1129 |
-
" run(f'cp -f -n {ssl}/* {_install_path}/frpc/')\n",
|
| 1130 |
-
" run(f'chmod +x {_install_path}/frpc/frpc')\n",
|
| 1131 |
-
" run(f'{_install_path}/frpc/frpc -v')\n",
|
| 1132 |
-
"\n",
|
| 1133 |
-
"def startProxy():\n",
|
| 1134 |
-
" if _useNgrok:\n",
|
| 1135 |
-
" startNgrok(ngrokToken,_server_port)\n",
|
| 1136 |
-
" if _useFrpc:\n",
|
| 1137 |
-
" startFrpc('frpc_proxy',frpcStartArg)"
|
| 1138 |
-
]
|
| 1139 |
-
},
|
| 1140 |
-
{
|
| 1141 |
-
"cell_type": "markdown",
|
| 1142 |
-
"metadata": {},
|
| 1143 |
-
"source": [
|
| 1144 |
-
"## NGINX 反向代理\n",
|
| 1145 |
-
"\n",
|
| 1146 |
-
"---"
|
| 1147 |
-
]
|
| 1148 |
-
},
|
| 1149 |
-
{
|
| 1150 |
-
"cell_type": "code",
|
| 1151 |
-
"execution_count": null,
|
| 1152 |
-
"metadata": {
|
| 1153 |
-
"_kg_hide-input": true,
|
| 1154 |
-
"_kg_hide-output": true,
|
| 1155 |
-
"trusted": true
|
| 1156 |
-
},
|
| 1157 |
-
"outputs": [],
|
| 1158 |
-
"source": [
|
| 1159 |
-
"\n",
|
| 1160 |
-
"# nginx 反向代理配置文件\n",
|
| 1161 |
-
"def localProxy():\n",
|
| 1162 |
-
" def getProxyLocation(subPath:str, localServer:str):\n",
|
| 1163 |
-
" return '''\n",
|
| 1164 |
-
" location '''+ subPath +'''\n",
|
| 1165 |
-
" {\n",
|
| 1166 |
-
" proxy_pass '''+ localServer +''';\n",
|
| 1167 |
-
" \n",
|
| 1168 |
-
" client_max_body_size 1000m;\n",
|
| 1169 |
-
" proxy_set_header Host $http_host;\n",
|
| 1170 |
-
" proxy_set_header X-Real-IP $remote_addr;\n",
|
| 1171 |
-
" proxy_set_header X-Real-Port $remote_port;\n",
|
| 1172 |
-
" proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n",
|
| 1173 |
-
" proxy_set_header X-Forwarded-Proto $scheme;\n",
|
| 1174 |
-
" proxy_set_header X-Forwarded-Host $host;\n",
|
| 1175 |
-
" proxy_set_header X-Forwarded-Port $server_port;\n",
|
| 1176 |
-
" proxy_set_header REMOTE-HOST $remote_addr;\n",
|
| 1177 |
-
" proxy_connect_timeout 3000s;\n",
|
| 1178 |
-
" proxy_send_timeout 3000s;\n",
|
| 1179 |
-
" proxy_read_timeout 3000s;\n",
|
| 1180 |
-
" proxy_http_version 1.1;\n",
|
| 1181 |
-
" proxy_set_header Upgrade $http_upgrade;\n",
|
| 1182 |
-
" proxy_set_header Connection 'upgrade';\n",
|
| 1183 |
-
" add_header Access-Control-Allow-Origin * always;\n",
|
| 1184 |
-
" add_header Access-Control-Allow-Headers *;\n",
|
| 1185 |
-
" add_header Access-Control-Allow-Methods \"GET, POST, PUT, OPTIONS\";\n",
|
| 1186 |
-
" }\n",
|
| 1187 |
-
" \n",
|
| 1188 |
-
" '''\n",
|
| 1189 |
-
" \n",
|
| 1190 |
-
" conf = '''\n",
|
| 1191 |
-
"server\n",
|
| 1192 |
-
"{\n",
|
| 1193 |
-
" listen '''+str(_server_port)+''';\n",
|
| 1194 |
-
" listen [::]:'''+str(_server_port)+''';\n",
|
| 1195 |
-
" server_name 127.0.0.1 localhost 0.0.0.0 \"\";\n",
|
| 1196 |
-
" \n",
|
| 1197 |
-
" fastcgi_send_timeout 3000s;\n",
|
| 1198 |
-
" fastcgi_read_timeout 3000s;\n",
|
| 1199 |
-
" fastcgi_connect_timeout 3000s;\n",
|
| 1200 |
-
" \n",
|
| 1201 |
-
" if ($request_method = OPTIONS) {\n",
|
| 1202 |
-
" return 200;\n",
|
| 1203 |
-
" }\n",
|
| 1204 |
-
" \n",
|
| 1205 |
-
" '''+ ''.join([getProxyLocation(key,_proxy_path[key]) for key in sorted(_proxy_path.keys(), key=len)[::-1]]) +'''\n",
|
| 1206 |
-
"}\n",
|
| 1207 |
-
"'''\n",
|
| 1208 |
-
" echoToFile(conf,'/etc/nginx/conf.d/proxy_nginx.conf')\n",
|
| 1209 |
-
" if not check_service('localhost',_server_port):\n",
|
| 1210 |
-
" run(f'''nginx -c /etc/nginx/nginx.conf''')\n",
|
| 1211 |
-
" run(f'''nginx -s reload''')"
|
| 1212 |
-
]
|
| 1213 |
-
},
|
| 1214 |
-
{
|
| 1215 |
-
"cell_type": "markdown",
|
| 1216 |
-
"metadata": {},
|
| 1217 |
-
"source": [
|
| 1218 |
-
"## 线程清理工具\n",
|
| 1219 |
-
"\n",
|
| 1220 |
-
"---\n",
|
| 1221 |
-
"\n",
|
| 1222 |
-
"清理线程名以 solo_ 开头的所有线程"
|
| 1223 |
-
]
|
| 1224 |
-
},
|
| 1225 |
-
{
|
| 1226 |
-
"cell_type": "code",
|
| 1227 |
-
"execution_count": null,
|
| 1228 |
-
"metadata": {
|
| 1229 |
-
"_kg_hide-input": true,
|
| 1230 |
-
"trusted": true
|
| 1231 |
-
},
|
| 1232 |
-
"outputs": [],
|
| 1233 |
-
"source": [
|
| 1234 |
-
"import inspect\n",
|
| 1235 |
-
"import ctypes\n",
|
| 1236 |
-
"\n",
|
| 1237 |
-
"def _async_raise(tid, exctype):\n",
|
| 1238 |
-
" \"\"\"raises the exception, performs cleanup if needed\"\"\"\n",
|
| 1239 |
-
" tid = ctypes.c_long(tid)\n",
|
| 1240 |
-
" if not inspect.isclass(exctype):\n",
|
| 1241 |
-
" exctype = type(exctype)\n",
|
| 1242 |
-
" res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))\n",
|
| 1243 |
-
" if res == 0:\n",
|
| 1244 |
-
" raise ValueError(\"invalid thread id\")\n",
|
| 1245 |
-
" elif res != 1:\n",
|
| 1246 |
-
" # \"\"\"if it returns a number greater than one, you're in trouble,\n",
|
| 1247 |
-
" # and you should call it again with exc=NULL to revert the effect\"\"\"\n",
|
| 1248 |
-
" ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)\n",
|
| 1249 |
-
" raise SystemError(\"PyThreadState_SetAsyncExc failed\")\n",
|
| 1250 |
-
"\n",
|
| 1251 |
-
"def stop_thread(thread):\n",
|
| 1252 |
-
" _async_raise(thread.ident, SystemExit)\n",
|
| 1253 |
-
"\n",
|
| 1254 |
-
"def stop_solo_threads():\n",
|
| 1255 |
-
" global _runing\n",
|
| 1256 |
-
" _runing = False\n",
|
| 1257 |
-
" # 获取当前所有活动的线程\n",
|
| 1258 |
-
" threads = threading.enumerate()\n",
|
| 1259 |
-
" # 关闭之前创建的子线程\n",
|
| 1260 |
-
" for thread in threads:\n",
|
| 1261 |
-
" if thread.name.startswith('solo_'):\n",
|
| 1262 |
-
" print(f'结束线程:{thread.name}')\n",
|
| 1263 |
-
" try:\n",
|
| 1264 |
-
" stop_thread(thread)\n",
|
| 1265 |
-
" except socket.error:\n",
|
| 1266 |
-
" print(f'结束线程:{thread.name} 执行失败')"
|
| 1267 |
-
]
|
| 1268 |
-
},
|
| 1269 |
-
{
|
| 1270 |
-
"cell_type": "markdown",
|
| 1271 |
-
"metadata": {
|
| 1272 |
-
"id": "Ve3p8oOkLCtE"
|
| 1273 |
-
},
|
| 1274 |
-
"source": [
|
| 1275 |
-
"# webui 安装和配置函数\n",
|
| 1276 |
-
"---"
|
| 1277 |
-
]
|
| 1278 |
-
},
|
| 1279 |
-
{
|
| 1280 |
-
"cell_type": "code",
|
| 1281 |
-
"execution_count": null,
|
| 1282 |
-
"metadata": {
|
| 1283 |
-
"_kg_hide-input": true,
|
| 1284 |
-
"id": "GTjyBJihLCtE",
|
| 1285 |
-
"trusted": true
|
| 1286 |
-
},
|
| 1287 |
-
"outputs": [],
|
| 1288 |
-
"source": [
|
| 1289 |
-
"envInstalled=False\n",
|
| 1290 |
-
"quickStart = False\n",
|
| 1291 |
-
"#安装\n",
|
| 1292 |
-
"def install():\n",
|
| 1293 |
-
" print('安装')\n",
|
| 1294 |
-
" os.chdir(f'''{_install_path}''')\n",
|
| 1295 |
-
" run(f'''git lfs install''')\n",
|
| 1296 |
-
" run(f'''git config --global credential.helper store''')\n",
|
| 1297 |
-
" for requirement in requirements:\n",
|
| 1298 |
-
" run(f'pip install {requirement}')\n",
|
| 1299 |
-
" if _reLoad:\n",
|
| 1300 |
-
" run(f'''rm -rf {_install_path}/{_ui_dir_name}''')\n",
|
| 1301 |
-
" if Path(f\"{_ui_dir_name}\").exists():\n",
|
| 1302 |
-
" os.chdir(f'''{_install_path}/{_ui_dir_name}/''')\n",
|
| 1303 |
-
" run(f'''git checkout .''')\n",
|
| 1304 |
-
" run(f'''git pull''')\n",
|
| 1305 |
-
" else:\n",
|
| 1306 |
-
" run(f'''git clone --recursive {_sd_git_repo} {_ui_dir_name}''')\n",
|
| 1307 |
-
" if not Path(f'''{_install_path}/{_ui_dir_name}''').exists():\n",
|
| 1308 |
-
" print('sd-webui主程序安装失败,请检查 sd_git_repo 配置的值是否正确')\n",
|
| 1309 |
-
" sys.exit(0)\n",
|
| 1310 |
-
" os.chdir(f'''{_install_path}/{_ui_dir_name}''')\n",
|
| 1311 |
-
" print('安装 完成')\n",
|
| 1312 |
-
"\n",
|
| 1313 |
-
"# 链接输出目录\n",
|
| 1314 |
-
"def link_dir():\n",
|
| 1315 |
-
" print('链接输出目录')\n",
|
| 1316 |
-
" # 链接图片输出目录\n",
|
| 1317 |
-
" run(f'''mkdir -p {_output_path}/outputs''')\n",
|
| 1318 |
-
" run(f'''rm -rf {_install_path}/{_ui_dir_name}/outputs''')\n",
|
| 1319 |
-
" run(f'''ln -s -r {_output_path}/outputs {_install_path}/{_ui_dir_name}/''')\n",
|
| 1320 |
-
" # 输出收藏目录\n",
|
| 1321 |
-
" run(f'''mkdir -p {_output_path}/log''')\n",
|
| 1322 |
-
" run(f'''rm -rf {_install_path}/{_ui_dir_name}/log''')\n",
|
| 1323 |
-
" run(f'''ln -s -r {_output_path}/log {_install_path}/{_ui_dir_name}/''')\n",
|
| 1324 |
-
" # 链接训练输出目录 文件夹链接会导致功能不能用\n",
|
| 1325 |
-
" run(f'''rm -rf {_install_path}/{_ui_dir_name}/textual_inversion''')\n",
|
| 1326 |
-
" run(f'''mkdir -p {_output_path}/textual_inversion/''')\n",
|
| 1327 |
-
" run(f'''ln -s -r {_output_path}/textual_inversion {_install_path}/{_ui_dir_name}/''')\n",
|
| 1328 |
-
" print('链接输出目录 完成') \n",
|
| 1329 |
-
"\n",
|
| 1330 |
-
"def install_optimizing():\n",
|
| 1331 |
-
" run('add-apt-repository ppa:deadsnakes/ppa -y')\n",
|
| 1332 |
-
" run('apt update -y')\n",
|
| 1333 |
-
" run('apt install nginx -y')\n",
|
| 1334 |
-
" # run('apt install python3.10 -y')\n",
|
| 1335 |
-
" \n",
|
| 1336 |
-
"#安装依赖\n",
|
| 1337 |
-
"def install_dependencies():\n",
|
| 1338 |
-
" print('安装需要的python环境')\n",
|
| 1339 |
-
" global envInstalled\n",
|
| 1340 |
-
" global venvPath\n",
|
| 1341 |
-
" if Path(f'{_install_path}/{_ui_dir_name}/venv').exists():\n",
|
| 1342 |
-
" print('跳过安装python环境')\n",
|
| 1343 |
-
" envInstalled = True\n",
|
| 1344 |
-
" return\n",
|
| 1345 |
-
" \n",
|
| 1346 |
-
" if quickStart and Path(venvPath).exists():\n",
|
| 1347 |
-
" print('解压环境')\n",
|
| 1348 |
-
" mkdirs(f'{_install_path}/{_ui_dir_name}/venv')\n",
|
| 1349 |
-
"# run('python3.10 -m venv venv',cwd=f'{_install_path}/{_ui_dir_name}')\n",
|
| 1350 |
-
" run(f'tar -xf {venvPath} -C ./venv',cwd=f'{_install_path}/{_ui_dir_name}')\n",
|
| 1351 |
-
" run(f'rm -f {_install_path}/{_ui_dir_name}/venv/bin/pip*')\n",
|
| 1352 |
-
" run(f'rm -f {_install_path}/{_ui_dir_name}/venv/bin/python*')\n",
|
| 1353 |
-
" venv.create(f'{_install_path}/{_ui_dir_name}/venv')\n",
|
| 1354 |
-
" if not Path(f'{_install_path}/{_ui_dir_name}/venv/bin/pip').exists():\n",
|
| 1355 |
-
" run('curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py')\n",
|
| 1356 |
-
" run(f'{_install_path}/{_ui_dir_name}/venv/bin/python3 get-pip.py')\n",
|
| 1357 |
-
" \n",
|
| 1358 |
-
" if not quickStart:\n",
|
| 1359 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python3 -V''')\n",
|
| 1360 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python3 -m pip -V''')\n",
|
| 1361 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python -m pip install torch==2.3.1 torchvision==0.18.1 torchaudio==2.3.1 --index-url https://download.pytorch.org/whl/cu121''')\n",
|
| 1362 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python -m pip install xformers==0.0.27''')\n",
|
| 1363 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python -m pip install -r requirements_versions.txt''')\n",
|
| 1364 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python -m pip install spandrel==0.3.0''')\n",
|
| 1365 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python -m pip install opencv-python''')\n",
|
| 1366 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python -m pip install pydantic==1.10.15''')\n",
|
| 1367 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python -m pip install transformers -U''')\n",
|
| 1368 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python -m pip install llama-cpp-python''')\n",
|
| 1369 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python -m pip install pytorch_lightning==2.3.3 torchsde==0.2.6 spandrel==0.3.4''')\n",
|
| 1370 |
-
" \n",
|
| 1371 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python3 -m pip install open-clip-torch -U''')\n",
|
| 1372 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python3 -m pip install protobuf==4.25.8''')\n",
|
| 1373 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python3 -m pip install blendmodes==2022''')\n",
|
| 1374 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python3 -m pip install Pillow==9.5.0''')\n",
|
| 1375 |
-
" run(f'''{_install_path}/{_ui_dir_name}/venv/bin/python3 -m pip install basicsr''')\n",
|
| 1376 |
-
" \n",
|
| 1377 |
-
" get_ipython().system(f'''{_install_path}/{_ui_dir_name}/venv/bin/python3 -m pip install basicsr''')\n",
|
| 1378 |
-
"\n",
|
| 1379 |
-
" envInstalled = True\n",
|
| 1380 |
-
" print('安装需要的python环境 完成')\n",
|
| 1381 |
-
" \n",
|
| 1382 |
-
"# 个性化配置 \n",
|
| 1383 |
-
"def use_config():\n",
|
| 1384 |
-
" print('使用自定义配置 包括tag翻译 \\n')\n",
|
| 1385 |
-
" run(f'''mkdir -p {_install_path}/temp''')\n",
|
| 1386 |
-
" run(f'git clone {_sd_config_git_repu} sd-configs',cwd=f'{_install_path}/temp')\n",
|
| 1387 |
-
" run(f'cp -r -f -n {_install_path}/temp/sd-configs/dist/* {_install_path}/{_ui_dir_name}')\n",
|
| 1388 |
-
" if not Path(_ui_config_file).exists() and _ui_config_file != 'ui-config.json': # ui配置文件\n",
|
| 1389 |
-
" run(f'''mkdir -p {_ui_config_file[:_ui_config_file.rfind('/')]}''')\n",
|
| 1390 |
-
" run(f'cp -f -n {_install_path}/{_ui_dir_name}/ui-config.json {_ui_config_file}')\n",
|
| 1391 |
-
" if not Path(_setting_file).exists() and _setting_file != 'config.json': # 设置配置文件\n",
|
| 1392 |
-
" run(f'''mkdir -p {_setting_file[:_setting_file.rfind('/')]}''')\n",
|
| 1393 |
-
" run(f'cp -f -n {_install_path}/{_ui_dir_name}/config.json {_setting_file}')\n",
|
| 1394 |
-
"\n",
|
| 1395 |
-
"def copy_last_log_to_images():\n",
|
| 1396 |
-
" if not Path(f'{_install_path}/{_ui_dir_name}/log/images').exists(): mkdirs(f'{_install_path}/{_ui_dir_name}/log/images')\n",
|
| 1397 |
-
" print('复制编号最大的一张收藏图到输出目录,用于保持编号,否则会出现收藏的图片被覆盖的情况')\n",
|
| 1398 |
-
" img_list = os.listdir(f'{_install_path}/{_ui_dir_name}/log/images')\n",
|
| 1399 |
-
" last_img_path = ''\n",
|
| 1400 |
-
" last_img_num = 0\n",
|
| 1401 |
-
" for img in img_list:\n",
|
| 1402 |
-
" if re.findall(r'^\\d+-',str(img)):\n",
|
| 1403 |
-
" num = int(re.findall(r'^\\d+-',str(img))[0][:-1])\n",
|
| 1404 |
-
" if num > last_img_num:\n",
|
| 1405 |
-
" last_img_path = img\n",
|
| 1406 |
-
" last_img_num = num\n",
|
| 1407 |
-
" \n",
|
| 1408 |
-
" if not last_img_path: return\n",
|
| 1409 |
-
" \n",
|
| 1410 |
-
" print(f'{_install_path}/{_ui_dir_name}/log/images/{last_img_path} {_install_path}/{_ui_dir_name}/outputs/txt2img-images')\n",
|
| 1411 |
-
" run(f'''mkdir -p {_install_path}/{_ui_dir_name}/outputs/txt2img-images''')\n",
|
| 1412 |
-
" run(f'''cp -f {_install_path}/{_ui_dir_name}/log/images/{last_img_path} {_install_path}/{_ui_dir_name}/outputs/txt2img-images/''')\n",
|
| 1413 |
-
" \n",
|
| 1414 |
-
" print(f'{_install_path}/{_ui_dir_name}/log/images/{last_img_path} {_install_path}/{_ui_dir_name}/outputs/img2img-images')\n",
|
| 1415 |
-
" run(f'''mkdir -p {_install_path}/{_ui_dir_name}/outputs/img2img-images''')\n",
|
| 1416 |
-
" run(f'''cp -f {_install_path}/{_ui_dir_name}/log/images/{last_img_path} {_install_path}/{_ui_dir_name}/outputs/img2img-images/''')\n",
|
| 1417 |
-
" \n",
|
| 1418 |
-
"def start_webui(i):\n",
|
| 1419 |
-
" # 只要不爆内存,其他方式关闭后会再次重启 访问地址会发生变化\n",
|
| 1420 |
-
" print(i,'--port',str(_server_port+1+i))\n",
|
| 1421 |
-
" if i>0:\n",
|
| 1422 |
-
" print(f'使用第{i+1}张显卡启动第{i+1}个服务,通过frpc或nrgok地址后加{_sub_path[i]}进行访问')\n",
|
| 1423 |
-
"\n",
|
| 1424 |
-
" restart_times = 0\n",
|
| 1425 |
-
" last_restart_time = time.time()\n",
|
| 1426 |
-
" while _runing:\n",
|
| 1427 |
-
" os.chdir(f'{_install_path}/{_ui_dir_name}')\n",
|
| 1428 |
-
" root_path = _sub_path[i]\n",
|
| 1429 |
-
" if root_path.endswith('/'): root_path = root_path[:-1]\n",
|
| 1430 |
-
" if torch.cuda.device_count() == 2 and not _multi_case:\n",
|
| 1431 |
-
" os.environ['CUDA_VISIBLE_DEVICES']='0,1'\n",
|
| 1432 |
-
" get_ipython().system(f'''venv/bin/python3 launch.py --port {str(_server_port+1+i)} --subpath={_sub_path[i]}''')\n",
|
| 1433 |
-
" else: \n",
|
| 1434 |
-
" get_ipython().system(f'''venv/bin/python3 launch.py --device-id={i} --port {str(_server_port+1+i)} --subpath={_sub_path[i]}''')\n",
|
| 1435 |
-
" print('10秒后重启服务')\n",
|
| 1436 |
-
" if time.time() - last_restart_time < 60:\n",
|
| 1437 |
-
" restart_times = restart_times + 1\n",
|
| 1438 |
-
" else:\n",
|
| 1439 |
-
" restart_times = 0\n",
|
| 1440 |
-
" last_restart_time = time.time()\n",
|
| 1441 |
-
" if restart_times >3 :\n",
|
| 1442 |
-
" # 如果180秒内重启了3此,将不再自动重启\n",
|
| 1443 |
-
" break\n",
|
| 1444 |
-
" time.sleep(10)\n",
|
| 1445 |
-
" \n",
|
| 1446 |
-
"# 启动\n",
|
| 1447 |
-
"def start():\n",
|
| 1448 |
-
" print('启动webui')\n",
|
| 1449 |
-
" os.chdir(f'''{_install_path}/{_ui_dir_name}''')\n",
|
| 1450 |
-
" args = ''\n",
|
| 1451 |
-
" if _ui_config_file is not None and _ui_config_file != '' and Path(_ui_config_file).exists(): # ui配置文件\n",
|
| 1452 |
-
" args += ' --ui-config-file=' + _ui_config_file\n",
|
| 1453 |
-
" if _setting_file is not None and _setting_file != '' and Path(_setting_file).exists(): # 设置配置文件\n",
|
| 1454 |
-
" args += ' --ui-settings-file=' + _setting_file\n",
|
| 1455 |
-
" args += ' ' + otherArgs\n",
|
| 1456 |
-
" os.environ['COMMANDLINE_ARGS']=args\n",
|
| 1457 |
-
" run(f'''echo COMMANDLINE_ARGS=$COMMANDLINE_ARGS''')\n",
|
| 1458 |
-
" os.environ['REQS_FILE']='requirements_versions.txt'\n",
|
| 1459 |
-
"\n",
|
| 1460 |
-
" with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:\n",
|
| 1461 |
-
" for i in range(torch.cuda.device_count() if _multi_case else 1):\n",
|
| 1462 |
-
" executor.submit(start_webui,i)\n",
|
| 1463 |
-
" while _runing and not check_service('localhost',str(_server_port+1+i)): # 当当前服务启动完成才允许退出此次循环\n",
|
| 1464 |
-
" time.sleep(5)\n",
|
| 1465 |
-
" if not _runing: break\n",
|
| 1466 |
-
" time.sleep(10)"
|
| 1467 |
-
]
|
| 1468 |
-
},
|
| 1469 |
-
{
|
| 1470 |
-
"cell_type": "markdown",
|
| 1471 |
-
"metadata": {
|
| 1472 |
-
"id": "qLvsk8ByLCtF"
|
| 1473 |
-
},
|
| 1474 |
-
"source": [
|
| 1475 |
-
"# 入口函数\n",
|
| 1476 |
-
"---"
|
| 1477 |
-
]
|
| 1478 |
-
},
|
| 1479 |
-
{
|
| 1480 |
-
"cell_type": "code",
|
| 1481 |
-
"execution_count": null,
|
| 1482 |
-
"metadata": {
|
| 1483 |
-
"_kg_hide-input": true,
|
| 1484 |
-
"id": "IOKjaMlcLCtF",
|
| 1485 |
-
"trusted": true
|
| 1486 |
-
},
|
| 1487 |
-
"outputs": [],
|
| 1488 |
-
"source": [
|
| 1489 |
-
"\n",
|
| 1490 |
-
"# 启动非webui相关的的内容,加快启动速度\n",
|
| 1491 |
-
"def main():\n",
|
| 1492 |
-
" global envInstalled\n",
|
| 1493 |
-
" global huggingface_is_init\n",
|
| 1494 |
-
" global _runing\n",
|
| 1495 |
-
" init_start_conf()\n",
|
| 1496 |
-
" stop_solo_threads()\n",
|
| 1497 |
-
" print('启动...')\n",
|
| 1498 |
-
" startTicks = time.time()\n",
|
| 1499 |
-
" time.sleep(5)\n",
|
| 1500 |
-
" _runing = True\n",
|
| 1501 |
-
" isInstall = True if os.getenv('IsInstall','False') == 'True' else False\n",
|
| 1502 |
-
" _proxy_path[_sub_path[0]] = f'http://127.0.0.1:{_server_port+1}/'\n",
|
| 1503 |
-
" _proxy_path[_sub_path[1]] = f'http://127.0.0.1:{_server_port+2}/'\n",
|
| 1504 |
-
" proxy_thread = threading.Thread(target = startProxy, daemon=True, name='solo_startProxy')\n",
|
| 1505 |
-
" proxy_thread.start()\n",
|
| 1506 |
-
" if isInstall is False or _reLoad: \n",
|
| 1507 |
-
" print('安装运行环境')\n",
|
| 1508 |
-
" os.environ['MPLBACKEND'] = 'Agg'\n",
|
| 1509 |
-
" install()\n",
|
| 1510 |
-
" link_dir()\n",
|
| 1511 |
-
" init_huggingface()\n",
|
| 1512 |
-
" install_optimizing()\n",
|
| 1513 |
-
" if not _skip_webui:\n",
|
| 1514 |
-
" threading.Thread(target = install_dependencies,daemon=True,name='solo_install_dependencies').start()\n",
|
| 1515 |
-
" else: envInstalled = True\n",
|
| 1516 |
-
" link_or_download_flie(replace_path(_async_downloading), _link_instead_of_copy=_link_instead_of_copy,\n",
|
| 1517 |
-
" base_path=f'{_install_path}/{_ui_dir_name}')\n",
|
| 1518 |
-
" if huggingface_is_init:\n",
|
| 1519 |
-
" threading.Thread(target = download__huggingface_repo,daemon=True,\n",
|
| 1520 |
-
" args=([_huggingface_repo]),\n",
|
| 1521 |
-
" kwargs={\"callback\":copy_last_log_to_images},\n",
|
| 1522 |
-
" name='solo_download__huggingface_repo').start()\n",
|
| 1523 |
-
" \n",
|
| 1524 |
-
" link_or_download_flie(replace_path(_before_downloading), _link_instead_of_copy=_link_instead_of_copy,\n",
|
| 1525 |
-
" base_path=f'{_install_path}/{_ui_dir_name}',is_await=True,sync=True)\n",
|
| 1526 |
-
" t = 0\n",
|
| 1527 |
-
" while _runing and not envInstalled:\n",
|
| 1528 |
-
" if t%10==0:\n",
|
| 1529 |
-
" print('等待python环境安装...')\n",
|
| 1530 |
-
" t = t+1\n",
|
| 1531 |
-
" time.sleep(1)\n",
|
| 1532 |
-
" use_config()\n",
|
| 1533 |
-
" os.environ['IsInstall'] = 'True'\n",
|
| 1534 |
-
" else:\n",
|
| 1535 |
-
" envInstalled = True\n",
|
| 1536 |
-
" localProxy()\n",
|
| 1537 |
-
" link_or_download_flie(replace_path(_before_start_sync_downloading), _link_instead_of_copy=_link_instead_of_copy,\n",
|
| 1538 |
-
" base_path=f'{_install_path}/{_ui_dir_name}',sync=True)\n",
|
| 1539 |
-
" if init_huggingface():\n",
|
| 1540 |
-
" start_sync_log_to_huggingface(_huggingface_repo)\n",
|
| 1541 |
-
" ticks = time.time()\n",
|
| 1542 |
-
" _on_before_start()\n",
|
| 1543 |
-
" print(\"加载耗时:\",(ticks - startTicks),\"秒\")\n",
|
| 1544 |
-
" if _skip_webui:\n",
|
| 1545 |
-
" print('跳过webui启动')\n",
|
| 1546 |
-
" proxy_thread.join()\n",
|
| 1547 |
-
" else:\n",
|
| 1548 |
-
" start()\n"
|
| 1549 |
-
]
|
| 1550 |
-
},
|
| 1551 |
-
{
|
| 1552 |
-
"cell_type": "markdown",
|
| 1553 |
-
"metadata": {
|
| 1554 |
-
"id": "0oaCRs2gLCtF"
|
| 1555 |
-
},
|
| 1556 |
-
"source": [
|
| 1557 |
-
"# 执行区域\n",
|
| 1558 |
-
"---"
|
| 1559 |
-
]
|
| 1560 |
-
},
|
| 1561 |
-
{
|
| 1562 |
-
"cell_type": "code",
|
| 1563 |
-
"execution_count": null,
|
| 1564 |
-
"metadata": {
|
| 1565 |
-
"_kg_hide-output": true,
|
| 1566 |
-
"id": "O3DR0DWHLCtF",
|
| 1567 |
-
"scrolled": true,
|
| 1568 |
-
"trusted": true
|
| 1569 |
-
},
|
| 1570 |
-
"outputs": [],
|
| 1571 |
-
"source": [
|
| 1572 |
-
"# 启动\n",
|
| 1573 |
-
"# _reLoad = True\n",
|
| 1574 |
-
"# hidden_console_info = False\n",
|
| 1575 |
-
"# run_by_none_device = True\n",
|
| 1576 |
-
"# show_shell_info = True\n",
|
| 1577 |
-
"\n",
|
| 1578 |
-
"print(f'当前sd的安装路径是:{_install_path}/{_ui_dir_name}')\n",
|
| 1579 |
-
"print(f'当前图片保存路径是:{_output_path}')\n",
|
| 1580 |
-
"print(f'当前数据集路径是:{_input_path}')\n",
|
| 1581 |
-
"\n",
|
| 1582 |
-
"print(update_desc)\n",
|
| 1583 |
-
"\n",
|
| 1584 |
-
"if _skip_start:\n",
|
| 1585 |
-
" print('已跳过自动启动,可手动执行 main() 进行启动。')\n",
|
| 1586 |
-
" print('''推荐的启动代码:\n",
|
| 1587 |
-
"try:\n",
|
| 1588 |
-
" check_gpu() # 检查是否存在gpu\n",
|
| 1589 |
-
" main()\n",
|
| 1590 |
-
"except KeyboardInterrupt:\n",
|
| 1591 |
-
" stop_solo_threads() # 中断后自动停止后台线程 (有部分功能在后台线程中运行)\n",
|
| 1592 |
-
" ''')\n",
|
| 1593 |
-
"else:\n",
|
| 1594 |
-
" try:\n",
|
| 1595 |
-
" check_gpu()\n",
|
| 1596 |
-
" main()\n",
|
| 1597 |
-
" except KeyboardInterrupt:\n",
|
| 1598 |
-
" stop_solo_threads()"
|
| 1599 |
-
]
|
| 1600 |
-
}
|
| 1601 |
-
],
|
| 1602 |
-
"metadata": {
|
| 1603 |
-
"kaggle": {
|
| 1604 |
-
"accelerator": "nvidiaTeslaT4",
|
| 1605 |
-
"dataSources": [
|
| 1606 |
-
{
|
| 1607 |
-
"datasetId": 2716934,
|
| 1608 |
-
"sourceId": 6167400,
|
| 1609 |
-
"sourceType": "datasetVersion"
|
| 1610 |
-
},
|
| 1611 |
-
{
|
| 1612 |
-
"datasetId": 3654544,
|
| 1613 |
-
"sourceId": 6346544,
|
| 1614 |
-
"sourceType": "datasetVersion"
|
| 1615 |
-
},
|
| 1616 |
-
{
|
| 1617 |
-
"datasetId": 2962375,
|
| 1618 |
-
"sourceId": 6720235,
|
| 1619 |
-
"sourceType": "datasetVersion"
|
| 1620 |
-
},
|
| 1621 |
-
{
|
| 1622 |
-
"datasetId": 3074484,
|
| 1623 |
-
"sourceId": 6817788,
|
| 1624 |
-
"sourceType": "datasetVersion"
|
| 1625 |
-
}
|
| 1626 |
-
],
|
| 1627 |
-
"isGpuEnabled": true,
|
| 1628 |
-
"isInternetEnabled": true,
|
| 1629 |
-
"language": "python",
|
| 1630 |
-
"sourceType": "notebook"
|
| 1631 |
-
},
|
| 1632 |
-
"kernelspec": {
|
| 1633 |
-
"display_name": "Python 3",
|
| 1634 |
-
"language": "python",
|
| 1635 |
-
"name": "python3"
|
| 1636 |
-
},
|
| 1637 |
-
"language_info": {
|
| 1638 |
-
"codemirror_mode": {
|
| 1639 |
-
"name": "ipython",
|
| 1640 |
-
"version": 3
|
| 1641 |
-
},
|
| 1642 |
-
"file_extension": ".py",
|
| 1643 |
-
"mimetype": "text/x-python",
|
| 1644 |
-
"name": "python",
|
| 1645 |
-
"nbconvert_exporter": "python",
|
| 1646 |
-
"pygments_lexer": "ipython3",
|
| 1647 |
-
"version": "3.10.12"
|
| 1648 |
-
}
|
| 1649 |
-
},
|
| 1650 |
-
"nbformat": 4,
|
| 1651 |
-
"nbformat_minor": 4
|
| 1652 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sdwui-start.ipynb
CHANGED
|
@@ -1 +1 @@
|
|
| 1 |
-
{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# 这只是一个完整项目的一部分 不能运行的 \n- 可以从这个地址运行 [点击打开](https://www.kaggle.com/viyiviyi/sdwui-before)\n---","metadata":{"id":"6zE2QeUKLCtC"}},{"cell_type":"code","source":"print('''\n路径说明\n* 可以使用 $install_path 或 {install_path} 来访问安装目录,写在字符串内也会生效\n* $output_path 或 {output_path} 可以访问输出目录\n* $input_path 或 {input_path} 可以访问输入目录 在kaggle是数据集根目录\n* 如果链接了谷歌云盘,将会在云盘根目录创建 sdwebui 的文件夹,文件夹内的 Input 目录将会作为 输入目录 Output 将会作为输出目录\n\n发布地址 https://www.kaggle.com/code/yiyiooo/stable-diffusion-webui-novelai\n\n更新日志\n*\n* 23-07-26\n* 增加可隐藏启动时的不重要信息 通过增加配置 [hidden_console_info = True] 开启\n* 增加可自定义下载或链接文件到指定目录\n* 配置方式:查看 https://www.kaggle.com/code/yiyiooo/stable-diffusion-webui-novelai 的 [其他文件列表]\n*\n* 23-07-22\n* 更新了可自动同步收藏目录到 https://huggingface.co/ 的功能\n* 可通过增加配置项 huggingface_token = \"token\" 和 huggingface_repo = “仓库id” 后使用此功能\n*\n* 23-07-18 \n* 如果有两个GPU 第二个GPU将会启动api服务,可用api的方式调用,和webui互相独立,绘图时不会导致另外一边卡顿\n* 通过/1/作为base url来访问这个api\n* 没有启动两个webui是因为,很大概率爆内存\n''')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from pathlib import Path\nimport os\nimport time\nimport re\nimport subprocess\nimport threading\nimport sys\nimport socket\nimport torch\nfrom typing import List\n\n# 检查gpu是否存在\nif torch.cuda.device_count() == 0:\n raise Exception('当前环境没有GPU')\n\ninstall_path=f\"{os.environ['HOME']}/sdwebui\" # 安装目录\noutput_path=f\"{os.environ['HOME']}/sdwebui/Output\" # 输出目录 如果使用google云盘 会在google云盘增加sdwebui/Output\ninput_path = '/kaggle/input' # 输入目录\n\ngoogle_drive = '' \n# 连接谷歌云\ntry:\n if useGooglrDrive:\n from google.colab import drive\n drive.mount(f'~/google_drive')\n google_drive = f\"{os.environ['HOME']}/google_drive/MyDrive\"\n output_path = f'{google_drive}/sdwebui/Output'\n input_path = f'{google_drive}/sdwebui/Input'\n !mkdir -p {input_path}\n # 设置文件路径\n if setting_file== '/kaggle/working/configs/config.json':\n setting_file = os.path.join(output_path,'configs/config.json')\n if ui_config_file == '/kaggle/working/configs/ui-config.json':\n ui_config_file = os.path.join(output_path,'configs/ui-config.json')\n print('''\n已经链接到谷歌云盘\n云盘根目录/sdwebui/Output 被链接为输出目录,图片和设置文件将会保存在此文件夹\n云盘根目录/sdwebui/Input 被链接为输入目录,环境变量名是 $input_path\n ''')\nexcept:\n useGooglrDrive = False\n\n!mkdir -p {install_path}\n!mkdir -p {output_path}\n\nos.environ['install_path'] = install_path\nos.environ['output_path'] = output_path\nos.environ['google_drive'] = google_drive\nos.environ['input_path'] = input_path\n\ndef replace_path(input_str:str):\n return input_str.replace('$install_path',install_path)\\\n .replace('{install_path}',install_path)\\\n .replace('$input_path',input_path)\\\n .replace('{input_path}',input_path)\\\n .replace('$output_path',output_path)\\\n .replace('{output_path}',output_path)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 模型目录 文件名称:链接的方式指定文件名\nmodelDirs = []+[replace_path(item.strip()) for item in 模型列表.split('\\n') if item.strip() ]\n# vae列表\nmodelVaeDirs = []+[replace_path(item.strip()) for item in VAE列表.split('\\n') if item.strip()]\n# 此配置内的目录下所有文件将加载到hypernetworks文件夹\nhypernetworksModelDirs = []+[replace_path(item.strip()) for item in hypernetworks列表.split('\\n') if item.strip()] \n# 此配置内的目录下所有文件将加载到embeddings文件夹\nembeddingsModelDirs = [] +[replace_path(item.strip()) for item in embeddings列表.split('\\n') if item.strip()]\n# 此配置内的目录下所有文件将加载到Lora文件夹\nloraModelDirs = []+[replace_path(item.strip()) for item in Lora列表.split('\\n') if item.strip()] \n\nlyCORISModelDirs = []+[replace_path(item.strip()) for item in LyCORIS列表.split('\\n') if item.strip()] \n# controlNet��件模型列表\ncontrolNetModels=[] +[replace_path(item.strip()) for item in controlNet模型列表.split('\\n') if item.strip()]\n# 插件列表\nextensions=[]+[replace_path(item.strip()) for item in 插件列表.split('\\n') if item.strip()]\n# 配置文件链接\nlinkHypernetworksDir=False # 链接 hypernetworks 目录到输出目录\nlinkEmbeddingsDir=False # 链接 embeddings 目录到输出目录\nlinkTextual_inversionDir=False # 链接 textual_inversion 目录到输出目录 如果需要保存训练过程的产出文件时建议开启\n\nngrokTokenFile = os.path.join(input_path,'configs/ngrok_token.txt') # 非必填 存放ngrokToken的文件的路径\nfrpcConfigFile = os.path.join(input_path,'configs/frpc_koishi.ini') # 非必填 frp 配置文件\n# ss证书目录 下载nginx的版本,把pem格式改成crt格式\nfrpcSSLFFlies =[os.path.join(input_path,'configs/koishi_ssl')]+[replace_path(item.strip()) for item in frpSSL文件.split('\\n') if item.strip() ]\n# frpc 文件目录 如果目录不存在,会自动下载,也可以在数据集搜索 viyiviyi/utils 添加\nfrpcExePath = os.path.join(input_path,'utils-tools/frpc')\n# 其他需要加载的webui启动参数 写到【参数列表】这个配置去\notherArgs = ' '.join([replace_path(item.strip()) for item in 参数列表.split('\\n') if item.strip()])\n\nvenvPath = os.path.join(input_path,'sd-webui-venv/venv.tar.bak') # 安装好的python环境 sd-webui-venv是一个公开是数据集 可以搜索添加\n\n# 用于使用kaggle api的token文件 参考 https://www.kaggle.com/docs/api\n# 此文件用于自动上传koishi的相关配置 也可以用于保存重要的输出文件\nkaggleApiTokenFile = os.path.join(input_path,'configs/kaggle.json')\n\nrequirements = []","metadata":{"_kg_hide-input":true,"id":"i3LhnwYHLCtC","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 这下面的是用于初始化一些值或者环境变量的,轻易别改\nfrpcStartArg = ''\n\nfrp配置文件或配置 = replace_path(frp配置文件或配置)\nngrok配置或文件地址 = replace_path(ngrok配置或文件地址)\n\n!mkdir -p $install_path/configFiles\nif Path(frp配置文件或配置.strip()).exists():\n frpcConfigFile = frp配置文件或配置.strip()\nif not Path(frpcConfigFile).exists(): \n if frp配置文件或配置.strip().startswith('-f'):\n frpcStartArg = frp配置文件或配置.strip()\n else:\n print('没有frpcp配置')\n useFrpc = False\nelse:\n os.system(f'cp -f {frpcConfigFile} {install_path}/configFiles/frpc_webui.ini')\n frpcConfigFile = f'{install_path}/configFiles/frpc_webui.ini'\n os.system(f'sed -i \"s/local_port = .*/local_port = {webuiPort}/g\" {frpcConfigFile}')\n frpcStartArg = f' -c {frpcConfigFile}'\n\nngrokToken=''\nif Path(ngrok配置或文件地址.strip()).exists():\n ngrokTokenFile = ngrok配置或文件地址.strip()\nif Path(ngrokTokenFile).exists():\n with open(ngrokTokenFile,encoding = \"utf-8\") as nkfile:\n ngrokToken = nkfile.readline()\nelif not ngrok配置或文件地址.strip().startswith('/'):\n ngrokToken=ngrok配置或文件地址.strip()\n \nif not Path(venvPath).exists():\n venvPath = os.path.join(input_path,'sd-webui-venv/venv.zip')\n","metadata":{"_kg_hide-input":true,"id":"a_GtG2ayLCtD","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_other_files():\n if '其他文件列表' not in globals():\n return {}\n other_flie_list = [replace_path(item.split('#')[0].strip()) for item in 其他文件列表.split('\\n') if item.strip()]\n other_flie_list_store = {}\n other_flie_list_store_name='default'\n other_flie_list_store_list_cache=[]\n for item in other_flie_list:\n if item.startswith('[') and item.endswith(']'):\n if not other_flie_list_store_name == 'default':\n other_flie_list_store[other_flie_list_store_name]=other_flie_list_store_list_cache\n other_flie_list_store_list_cache = []\n other_flie_list_store_name = item[1:-1]\n else:\n other_flie_list_store_list_cache.append(item)\n other_flie_list_store[other_flie_list_store_name]=other_flie_list_store_list_cache\n return other_flie_list_store","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os,sys,io\nsys_sys_stdout = sys.stdout\nclass HiddenPrints:\n def __enter__(self):\n if 'hidden_console_info' not in globals(): return\n if hidden_console_info:\n self._stdout = sys.stdout\n sys.stdout = self._stringio = io.StringIO()\n\n def __exit__(self, *args):\n if 'hidden_console_info' not in globals(): return\n if hidden_console_info:\n sys.stdout = self._stdout","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# kaggle public API\n\n**不能使用%cd这种会改变当前工作目录的命令,会导致和其他线程冲突**\n\n---","metadata":{"id":"p0uS-BLULCtD"}},{"cell_type":"code","source":"# 安装kaggle的api token文件\ndef initKaggleConfig():\n if Path('~/.kaggle/kaggle.json').exists():\n return True\n if Path(kaggleApiTokenFile).exists():\n !mkdir -p ~/.kaggle/\n os.system('cp '+kaggleApiTokenFile+' ~/.kaggle/kaggle.json')\n !chmod 600 ~/.kaggle/kaggle.json\n return True\n print('缺少kaggle的apiToken文件,访问:https://www.kaggle.com/你的kaggle用户名/account 获取')\n return False\n\ndef getUserName():\n if not initKaggleConfig(): return\n import kaggle\n return kaggle.KaggleApi().read_config_file()['username']\n\ndef createOrUpdateDataSet(path:str,datasetName:str):\n if not initKaggleConfig(): return\n print('创建或更新数据集 '+datasetName)\n import kaggle\n os.system('mkdir -p $install_path/kaggle_cache')\n os.system('rm -rf $install_path/kaggle_cache/*')\n datasetDirPath = install_path+'/kaggle_cache/'+datasetName\n os.system('mkdir -p '+datasetDirPath)\n os.system('cp -f '+path+' '+datasetDirPath+'/')\n username = getUserName()\n print(\"kaggle username:\"+username)\n datasetPath = username+'/'+datasetName\n datasetList = kaggle.api.dataset_list(mine=True,search=datasetPath)\n print(datasetList)\n if len(datasetList) == 0 or datasetPath not in [str(d) for d in datasetList]: # 创建 create\n os.system('kaggle datasets init -p' + datasetDirPath)\n metadataFile = datasetDirPath+'/dataset-metadata.json'\n os.system('sed -i s/INSERT_TITLE_HERE/'+ datasetName + '/g ' + metadataFile)\n os.system('sed -i s/INSERT_SLUG_HERE/'+ datasetName + '/g ' + metadataFile)\n os.system('cat '+metadataFile)\n os.system('kaggle datasets create -p '+datasetDirPath)\n print('create database done')\n else:\n kaggle.api.dataset_metadata(datasetPath,datasetDirPath)\n kaggle.api.dataset_create_version(datasetDirPath, 'auto update',dir_mode='zip')\n print('upload database done')\n\ndef downloadDatasetFiles(datasetName:str,outputPath:str):\n if not initKaggleConfig(): return\n print('下载数据集文件 '+datasetName)\n import kaggle\n username = getUserName()\n datasetPath = username+'/'+datasetName\n datasetList = kaggle.api.dataset_list(mine=True,search=datasetPath)\n if datasetPath not in [str(d) for d in datasetList]:\n return False\n os.system('mkdir -p '+outputPath)\n kaggle.api.dataset_download_files(datasetPath,path=outputPath,unzip=True)\n return True\n\n","metadata":{"_kg_hide-input":true,"id":"m8FJi4j0LCtD","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 同步文件夹到 huggingface\n","metadata":{}},{"cell_type":"code","source":"# 文件夹与 huggingface 同步\nif 'huggingface_token' in locals() and 'huggingface_repo' in locals():\n requirements.append('watchdog')\n requirements.append('huggingface_hub')\n\n\nhuggingface_is_init = False\n\ndef init_huggingface():\n if 'huggingface_token' not in globals() or 'huggingface_repo' not in globals():\n print('请增加配置项 huggingface_token = \"token\" 和 huggingface_repo = “仓库id” 后使用 huggingface 功能')\n return False\n global huggingface_is_init\n from huggingface_hub import HfApi,login,snapshot_download\n token = replace_path(huggingface_token)\n if Path(token).exists():\n with open(token,encoding = \"utf-8\") as nkfile:\n token = nkfile.readline()\n if not token.startswith('hf_'):\n print('huggingface token 不正确,请将 token 或 仅存放token 的txt文件路径填入 huggingface_token 配置')\n return False\n login(token)\n huggingface_is_init = True\n return True\n\n\ndef download_huggingface_repo(repo_id:str,dist_directory:str=None,repo_type='dataset',callback=None):\n if not huggingface_is_init:\n print('huggingface 相关功能未初始化 请调用 init_huggingface() 初始化')\n \n if not dist_directory:\n dist_directory = f'{install_path}/stable-diffusion-webui/log'\n \n from huggingface_hub import HfApi,login,snapshot_download\n \n api = HfApi()\n \n print('下载收藏的图片')\n snapshot_download(repo_id = huggingface_repo,\n local_dir = dist_directory,\n local_dir_use_symlinks = \"auto\",\n token=True,\n repo_type=repo_type\n )\n if callback:\n callback()\n\ndef start_sync_log_to_huggingface(repo_id:str,directory_to_watch:str=None,repo_type='dataset'):\n if not huggingface_is_init:\n print('huggingface 相关功能未初始化 请调用 init_huggingface() 初始化')\n \n from watchdog.observers import Observer\n from watchdog.events import FileSystemEventHandler\n from huggingface_hub import HfApi,login,snapshot_download\n \n # 配置监视的目录和 Hugging Face 仓库信息\n class FileChangeHandler(FileSystemEventHandler):\n def __init__(self, api, repo_id, repo_type):\n self.api = api\n self.repo_id = repo_id\n self.repo_type = repo_type\n def on_created(self, event):\n if not event.is_directory:\n # 上传新文件到 Hugging Face 仓库\n file_path = event.src_path\n file_name = os.path.basename(file_path)\n if file_name[-4:] not in ['.png','.jpg','.txt']: return\n try:\n self.api.upload_file(\n path_or_fileobj=file_path,\n path_in_repo=file_path.replace(directory_to_watch,''),\n repo_id=self.repo_id,\n repo_type=self.repo_type,\n )\n except Error as error:\n print(error)\n\n def on_deleted(self, event):\n if not event.is_directory:\n # 从 Hugging Face 仓库删除文件\n file_path = event.src_path\n file_name = os.path.basename(file_path)\n if file_name[-4:] not in ['.png','.jpg','.txt']: return\n try:\n self.api.delete_file(\n path_in_repo=file_path.replace(directory_to_watch,''),\n repo_id=self.repo_id,\n repo_type=self.repo_type,\n )\n except Error as error:\n print(error)\n\n def on_modified(self, event):\n if not event.is_directory:\n # 更新 Hugging Face 仓库中的文件\n file_path = event.src_path\n file_name = os.path.basename(file_path)\n if file_name[-4:] not in ['.png','.jpg','.txt']: return\n try:\n self.api.upload_file(\n path_or_fileobj=file_path,\n path_in_repo=file_path.replace(directory_to_watch,''),\n repo_id=self.repo_id,\n repo_type=self.repo_type,\n )\n except Error as error:\n print(error)\n\n def on_moved(self, event):\n if not event.is_directory:\n file_path = event.dest_path\n file_name = os.path.basename(file_path)\n if file_name[-4:] not in ['.png','.jpg','.txt']: return\n if event.dest_path.startswith(directory_to_watch):\n try:\n self.api.upload_file(\n path_or_fileobj=file_path,\n path_in_repo=file_path.replace(directory_to_watch,''),\n repo_id=self.repo_id,\n repo_type=self.repo_type,\n )\n except Error as error:\n print(error)\n\n api = HfApi()\n \n if not directory_to_watch:\n directory_to_watch = f'{install_path}/stable-diffusion-webui/log'\n # 创建观察者对象并注册文件变化处理程序\n event_handler = FileChangeHandler(api,repo_id,repo_type)\n observer = Observer()\n observer.schedule(event_handler, directory_to_watch, recursive=True)\n\n # 启动观察者\n observer.name = \"solo_directory_to_watch\"\n print(f'启动收藏图片文件夹监听,并自动同步到 huggingface {repo_type} : {repo_id}')\n observer.start()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 工具函数\n**不能使用%cd这种会改变当前工作目录的命令,会导致和其他线程冲突**\n\n---","metadata":{"id":"sswa04veLCtE"}},{"cell_type":"markdown","source":"一般工具函数","metadata":{}},{"cell_type":"code","source":"# 绕过 os.systen 的限制执行命令\ndef run(shell:str,shellName=''):\n if shellName == '': shellName = str(time.time())\n !mkdir -p $install_path/run_cache\n with open(install_path+'/run_cache/run_cache.'+shellName+'.sh','w') as sh:\n sh.write(shell)\n !bash {install_path}/run_cache/run_cache.{shellName}.sh\n\n# 连接多个路径字符串 让路径在shell命令中能正常的执行\ndef pathJoin(*paths:str):\n pathStr = ''\n for p in paths:\n pathStr += '\"'+p+'\"'\n pathStr = '\"*\"'.join(pathStr.split('*'))\n pathStr = '\"$\"'.join(pathStr.split('$'))\n pathStr = '\"(\"'.join(pathStr.split('('))\n pathStr = '\")\"'.join(pathStr.split(')'))\n pathStr = '\"{\"'.join(pathStr.split('{'))\n pathStr = '\"}\"'.join(pathStr.split('}'))\n pathStr = re.sub(r'\"\"','',pathStr)\n pathStr = re.sub(r'\\*{2,}','\"',pathStr)\n pathStr = re.sub(r'/{2,}','/',pathStr)\n pathStr = re.sub(r'/\\./','/',pathStr)\n return pathStr\n\n# 判断路径是不是一个文件或者可能指向一些文件\ndef pathIsFile(path):\n if Path(path).is_file():\n return True\n if re.search(r'\\.(ckpt|safetensors|png|jpg|txt|pt|pth|json|yaml|\\*)$',path):\n return True\n return False\n\ndef echoToFile(content:str,path:str):\n with open(path,'w') as sh:\n sh.write(content)\n\n# ngrok\ndef startNgrok(ngrokToken:str,ngrokLocalPort:int):\n from pyngrok import conf, ngrok\n try:\n conf.get_default().auth_token = ngrokToken\n conf.get_default().monitor_thread = False\n ssh_tunnels = ngrok.get_tunnels(conf.get_default())\n if len(ssh_tunnels) == 0:\n ssh_tunnel = ngrok.connect(ngrokLocalPort)\n print('ngrok 访问地址:'+ssh_tunnel.public_url)\n else:\n print('ngrok 访问地址:'+ssh_tunnels[0].public_url)\n except:\n print('启动ngrok出错')\n \ndef startFrpc(name,configFile):\n run(f'''\ncd $install_path/frpc/\n$install_path/frpc/frpc {configFile}\n ''',name)\n \ndef installProxyExe():\n if useFrpc:\n print('安装frpc')\n !mkdir -p $install_path/frpc\n if Path(frpcExePath).exists():\n os.system(f'cp -f -n {frpcExePath} $install_path/frpc/frpc')\n else:\n !wget \"https://huggingface.co/datasets/ACCA225/Frp/resolve/main/frpc\" -O $install_path/frpc/frpc\n \n for ssl in frpcSSLFFlies:\n if Path(ssl).exists():\n os.system('cp -f -n '+pathJoin(ssl,'/*')+' $install_path/frpc/')\n !chmod +x $install_path/frpc/frpc\n !$install_path/frpc/frpc -v\n if useNgrok:\n %pip install pyngrok\n\ndef startProxy():\n if useNgrok:\n startNgrok(ngrokToken,webuiPort)\n if useFrpc:\n startFrpc('frpc_proxy',frpcStartArg)\n\n \ndef zipPath(path:str,zipName:str,format='tar'):\n if path.startswith('$install_path'):\n path = path.replace('$install_path',install_path)\n if path.startswith('$output_path'):\n path = path.replace('$install_path',output_path)\n if not path.startswith('/'):\n path = pathJoin(install_path,'/stable-diffusion-webui','/',path)\n if Path(path).exists():\n if 'tar' == format:\n os.system('tar -cf $output_path/'+ zipName +'.tar -C '+ path +' . ')\n elif 'gz' == format:\n os.system('tar -czf $output_path/'+ zipName +'.tar.gz -C '+ path +' . ')\n return\n print('指定的目录不存在:'+path)\n\n \ndef check_service(host, port):\n try:\n socket.create_connection((host, port), timeout=5)\n return True\n except socket.error:\n return False","metadata":{"_kg_hide-input":true,"id":"coqQvTSLLCtE","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"文件下载工具","metadata":{}},{"cell_type":"code","source":"import os\nimport re\nimport requests\n\ndef download_file(url, filename, path,cache_path = ''):\n # 获取文件的真实文件名\n if not filename:\n with requests.get(url, stream=True) as r:\n if 'Content-Disposition' in r.headers:\n filename = r.headers['Content-Disposition'].split('filename=')[1].strip('\"')\n r.close()\n filename = re.sub(r'[\\\\/:*?\"<>|;]', '', filename)\n # 拼接文件的完整路径\n filepath = os.path.join(path, filename)\n if cache_path:\n cache_path = os.path.join(cache_path, filename)\n # 判断文件是否已存在\n if os.path.exists(filepath):\n print(f'{filename} already exists in {path}')\n return\n if cache_path and os.path.exists(cache_path):\n !ln -s -f {cache_path} {filepath}\n # 下载文件\n with requests.get(url, stream=True) as r:\n r.raise_for_status()\n with open(filepath, 'wb') as f:\n for chunk in r.iter_content(chunk_size=8192):\n if chunk:\n f.write(chunk)\n print(f'{filename} has been downloaded to {path}')\n \n# 加入文件到下载列表\ndef putDownloadFile(url:str,distDir:str,file_name:str=None):\n if re.match(r'^[^:]+:(https?|ftps?)://', url, flags=0):\n file_name = re.findall(r'^[^:]+:',url)[0][:-1]\n url = url[len(file_name)+1:]\n if not re.match(r'^(https?|ftps?)://',url):\n return\n file_name = re.sub(r'\\s+','_',file_name or '')\n dir = str(hash(url)).replace('-','')\n down_dir = f'{install_path}/down_cache/{dir}'\n !mkdir -p {down_dir}\n return [url,file_name,distDir,down_dir]\n\ndef get_file_size_in_gb(file_path):\n size_in_bytes = Path(file_path).stat().st_size\n size_in_gb = size_in_bytes / (1024 ** 3)\n return '%.2f' % size_in_gb\n \n# 下载文件\ndef startDownloadFiles(download_list):\n print('下载列表:\\n','\\n'.join([f'{item[0]} -> {item[2]}/{item[1]}' for item in download_list]))\n dist_list = []\n for dow_f in download_list:\n !mkdir -p {dow_f[3]}\n print('下载 名称:',dow_f[1],'url:',dow_f[0])\n download_file(dow_f[0],dow_f[1],dow_f[2],dow_f[3])\n \n\n","metadata":{"_kg_hide-input":true,"id":"THNUsEm_LCtE","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"NGINX 反向代理","metadata":{}},{"cell_type":"code","source":"\n# nginx ���向代理配置文件\ndef localProxy():\n conf = '''\nserver\n{\n listen '''+str(webuiPort)+''';\n listen [::]:'''+str(webuiPort)+''';\n server_name 127.0.0.1 localhost 0.0.0.0 \"\";\n \n if ($request_method = OPTIONS) {\n return 200;\n }\n fastcgi_send_timeout 10m;\n fastcgi_read_timeout 10m;\n fastcgi_connect_timeout 10m;\n location /1/\n {\n proxy_pass http://127.0.0.1:'''+str(webuiPort+2)+'''/;\n # add_header Set-Cookie \"subpath=1; expires=0; Path=/\";\n # proxy_set_header Set-Cookie \"subpath=1; expires=0; Path=/\";\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header REMOTE-HOST $remote_addr;\n proxy_set_header Upgrade $http_upgrade;\n proxy_set_header Connection upgrade;\n proxy_http_version 1.1;\n proxy_connect_timeout 10m;\n proxy_read_timeout 10m;\n }\n location /\n {\n set $proxy_url http://127.0.0.1:'''+str(webuiPort+1)+''';\n # if ($cookie_subpath = \"1\") {\n # set $proxy_url http://127.0.0.1:'''+str(webuiPort+2)+''';\n # }\n proxy_pass $proxy_url;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header REMOTE-HOST $remote_addr;\n proxy_set_header Upgrade $http_upgrade;\n proxy_set_header Connection upgrade;\n proxy_http_version 1.1;\n proxy_connect_timeout 10m;\n proxy_read_timeout 10m;\n }\n}\n'''\n echoToFile(conf,'/etc/nginx/conf.d/proxy_nginx.conf')\n if not check_service('localhost',webuiPort):\n !nginx -c /etc/nginx/nginx.conf\n !nginx -s reload\n ","metadata":{"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"线程清理工具","metadata":{}},{"cell_type":"code","source":"import inspect\nimport ctypes\n\ndef _async_raise(tid, exctype):\n \"\"\"raises the exception, performs cleanup if needed\"\"\"\n tid = ctypes.c_long(tid)\n if not inspect.isclass(exctype):\n exctype = type(exctype)\n res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))\n if res == 0:\n raise ValueError(\"invalid thread id\")\n elif res != 1:\n # \"\"\"if it returns a number greater than one, you're in trouble,\n # and you should call it again with exc=NULL to revert the effect\"\"\"\n ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)\n raise SystemError(\"PyThreadState_SetAsyncExc failed\")\n\ndef stop_thread(thread):\n _async_raise(thread.ident, SystemExit)\n\ndef stop_solo_threads():\n # 获取当前所有活动的线程\n threads = threading.enumerate()\n # 关闭之前创建的子线程\n for thread in threads:\n if thread.name.startswith('solo_'):\n print(thread.name)\n try:\n stop_thread(thread)\n except socket.error:\n print(f'结束进程:{thread.name} 执行失败')","metadata":{"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# webui 安装和配置函数\n---","metadata":{"id":"Ve3p8oOkLCtE"}},{"cell_type":"code","source":"envInstalled=False\nextensionsDone=False\n\n#安装webui\ndef install():\n print('安装webui')\n %cd $install_path\n with HiddenPrints():\n for requirement in requirements:\n !pip install {requirement}\n if reLoad:\n !rm -rf stable-diffusion-webui\n if Path(\"stable-diffusion-webui\").exists():\n %cd $install_path/stable-diffusion-webui/\n !git checkout .\n !git pull\n else:\n if mobileOptimize:\n !git clone https://github.com/viyiviyi/stable-diffusion-webui.git stable-diffusion-webui -b local # 修改了前端界面,手机使用更方便\n else:\n !git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui stable-diffusion-webui\n %cd {install_path}/stable-diffusion-webui\n print('安装webui 完成')\n\n# 链接输出目录\ndef link_dir():\n print('链接输出目录')\n # 链接输出目录 因为sd被部署在了stable-diffusion-webui目录,运行结束后为了方便下载就只有outputs目录放在output_path/目录下\n !mkdir -p $output_path/outputs\n !rm -rf $install_path/stable-diffusion-webui/outputs\n !ln -s -r $output_path/outputs $install_path/stable-diffusion-webui/ # 输出目录\n !mkdir -p $output_path/log\n !rm -rf $install_path/stable-diffusion-webui/log\n !ln -s -r $output_path/log $install_path/stable-diffusion-webui/\n # 链接 hypernetworks 目录\n if linkHypernetworksDir:\n !rm -rf $install_path/stable-diffusion-webui/models/hypernetworks\n !mkdir -p $output_path/hypernetworks\n !ln -s -r $output_path/hypernetworks $install_path/stable-diffusion-webui/models/\n # 链接 embeddings 目录\n if linkEmbeddingsDir:\n !rm -rf $install_path/stable-diffusion-webui/embeddings\n !mkdir -p $output_path/embeddings\n !ln -s -r $output_path/embeddings $install_path/stable-diffusion-webui/\n # 链接训练输出目录 文件夹链接会导致功能不能用\n if linkTextual_inversionDir:\n !rm -rf $install_path/stable-diffusion-webui/textual_inversion\n !mkdir -p $output_path/textual_inversion/\n !ln -s -r $output_path/textual_inversion $install_path/stable-diffusion-webui/\n print('链接输出目录 完成')\n \ndef link_or_download_flie(skip_down:bool,store:dict[str,List[str]]):\n download_list = []\n for dist_dir in store.keys():\n dist_path = os.path.join(f'{install_path}/stable-diffusion-webui',dist_dir)\n !mkdir -p {dist_path}\n for path in store[dist_dir]:\n if 'https://' in path or 'http://' in path:\n if skip_down:\n continue\n download_list.append(putDownloadFile(path,dist_path))\n elif pathIsFile(path):\n os.system(('cp -n' if enableLoadByCopy else 'ln -s')+' -f '+ pathJoin(path) +f' {dist_path}')\n else:\n os.system(('cp -n' if enableLoadByCopy else 'ln -s')+' -f '+ pathJoin(path,'/*.*') +f' {dist_path}')\n !rm -f {dist_path}/\\*.* \n startDownloadFiles(download_list)\n \n# 链接模型文件\ndef load_models(skip_url=False):\n print(('复制' if enableLoadByCopy else '链接') + '模型文件')\n if enableLoadByCopy:\n print('如果出现 No such file or directory 错误,可以忽略')\n store = get_other_files()\n store['models/Stable-diffusion'] = modelDirs + (store['models/Stable-diffusion'] if 'models/Stable-diffusion' in store else [])\n store['models/hypernetworks'] = hypernetworksModelDirs + (store['models/hypernetworks'] if 'models/hypernetworks' in store else [])\n store['models/embeddings'] = embeddingsModelDirs + (store['models/embeddings'] if 'models/embeddings' in store else [])\n store['models/Lora'] = loraModelDirs + (store['models/Lora'] if 'models/Lora' in store else [])\n store['models/LyCORIS'] = lyCORISModelDirs + (store['models/LyCORIS'] if 'models/LyCORIS' in store else [])\n store['models/VAE'] = modelVaeDirs + (store['models/VAE'] if 'models/VAE' in store else [])\n store['extensions/sd-webui-controlnet/models'] = controlNetModels + (store['extensions/sd-webui-controlnet/models'] if 'extensions/sd-webui-controlnet/models' in store else [])\n link_or_download_flie(skip_url,store)\n print(('复制' if enableLoadByCopy else '链接') + '模型文件 完成')\n\n#安装依赖\ndef install_dependencies():\n print('安装webui需要的python环境')\n global envInstalled\n global venvPath\n print(venvPath)\n \n with HiddenPrints():\n %env TF_CPP_MIN_LOG_LEVEL=1\n !apt -y update -qq\n !wget http://launchpadlibrarian.net/367274644/libgoogle-perftools-dev_2.5-2.2ubuntu3_amd64.deb\n !wget https://launchpad.net/ubuntu/+source/google-perftools/2.5-2.2ubuntu3/+build/14795286/+files/google-perftools_2.5-2.2ubuntu3_all.deb\n !wget https://launchpad.net/ubuntu/+source/google-perftools/2.5-2.2ubuntu3/+build/14795286/+files/libtcmalloc-minimal4_2.5-2.2ubuntu3_amd64.deb\n !wget https://launchpad.net/ubuntu/+source/google-perftools/2.5-2.2ubuntu3/+build/14795286/+files/libgoogle-perftools4_2.5-2.2ubuntu3_amd64.deb\n !apt -y install -qq libunwind8-dev\n !dpkg -i *.deb\n %env LD_PRELOAD=libtcmalloc.so\n !rm *.deb\n !sudo apt install nginx -y\n\n sh = f'cd {install_path}/stable-diffusion-webui\\n'\n if str(sys.version).startswith('3.8') or str(sys.version).startswith('3.9') or str(sys.version).startswith('3.10'):\n sh += 'python -m venv venv\\n'\n else:\n sh += '''\nadd-apt-repository ppa:deadsnakes/ppa -y\napt update\napt install python3.10 -y\npython3.10 -m venv venv\n'''\n if quickStart:\n if not Path(venvPath).exists():\n !mkdir -p {install_path}/venv_cache\n if not Path(f'{install_path}/venv_cache/venv.tar.bak').exists():\n download_file('https://huggingface.co/viyi/sdwui/resolve/main/venv.zip','venv.zip',f'{install_path}/venv_cache')\n !unzip {install_path}/venv_cache/venv.zip -d {install_path}/venv_cache\n venvPath = f'{install_path}/venv_cache/venv.tar.bak'\n !rm -rf {install_path}/venv_cache/venv.zip\n elif venvPath.endswith('.zip'):\n !mkdir -p {install_path}/venv_cache\n !unzip {venvPath} -d {install_path}/venv_cache\n venvPath = f'{install_path}/venv_cache/venv.tar.bak'\n\n sh += 'echo \"unzip venv\"\\n'\n sh += f'tar -xf {venvPath} -C ./venv\\n'\n sh += '\\n'\n with HiddenPrints():\n run(sh,'dependencies')\n if not Path(f'{install_path}/stable-diffusion-webui/venv/bin/pip').exists():\n !curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py\n with HiddenPrints():\n !{install_path}/stable-diffusion-webui/venv/bin/python3 get-pip.py\n\n !{install_path}/stable-diffusion-webui/venv/bin/python3 -V\n !{install_path}/stable-diffusion-webui/venv/bin/python3 -m pip -V\n\n if not quickStart or not Path(venvPath).exists():\n with HiddenPrints():\n !{install_path}/stable-diffusion-webui/venv/bin/python3 -m pip install -U torch==2.0.0+cu117 torchvision==0.15.1+cu117 torchaudio==2.0.1 --index-url https://download.pytorch.org/whl/cu117\n !{install_path}/stable-diffusion-webui/venv/bin/python3 -m pip install -U open-clip-torch xformers==0.0.19\n\n envInstalled = True\n print('安装webui需要的python环境 完成')\n\n# 安装插件\ndef install_extensions():\n global extensionsDone\n print('安装插件')\n sh = 'mkdir -p $install_path/stable-diffusion-webui/extensions \\n'\n sh = 'mkdir -p $install_path/cache/extensions \\n'\n sh += 'cd $install_path/cache/extensions \\n'\n for ex in extensions:\n sh += 'git clone ' + ex + ' \\n'\n sh += 'rsync -a $install_path/cache/extensions/* $install_path/stable-diffusion-webui/extensions \\n'\n sh += 'cd ../ && rm -rf $install_path/cache/extensions \\n'\n with HiddenPrints():\n run(sh,'extensions')\n extensionsDone = True\n print('安装插件 完成')\n \n# 个性化配置 \ndef use_config():\n print('使用自定义配置 包括tag翻译 \\n')\n %cd $install_path/stable-diffusion-webui\n !mkdir -p tmp\n %cd tmp\n !git clone {webui_settings} sd-configs\n !cp -rf sd-configs/dist/* $install_path/stable-diffusion-webui\n if not Path(ui_config_file).exists(): # ui配置文件\n !mkdir -p {ui_config_file[0:ui_config_file.rfind('/')]}\n os.system('cp -f -n $install_path/stable-diffusion-webui/ui-config.json '+ui_config_file)\n if not Path(setting_file).exists(): # 设置配置文件\n !mkdir -p {setting_file[0:setting_file.rfind('/')]}\n os.system('cp -f -n $install_path/stable-diffusion-webui/config.json '+setting_file)\n\ndef checkDefaultModel():\n print('检查默认模型文件是否存在 \\n')\n global usedCkpt\n if usedCkpt is not None and usedCkpt != '': # 设置启动时默认加载的模型\n if '.' in usedCkpt:\n if '/' in usedCkpt:\n usedCkpt = usedCkpt\n else:\n usedCkpt = install_path + '/stable-diffusion-webui/models/Stable-diffusion/' + usedCkpt\n else:\n for x in ['.ckpt','.safetensors']:\n if Path(install_path+'/stable-diffusion-webui/models/Stable-diffusion/' + usedCkpt+x).exists():\n usedCkpt = install_path+'/stable-diffusion-webui/models/Stable-diffusion/' + usedCkpt+x\n break\n if Path(usedCkpt).exists():\n return True\n else:\n if Path(usedCkpt).is_symlink():\n print('模型文件真实地址:'+os.readlink(usedCkpt))\n return False\n\ndef copy_last_log_to_images():\n print('复制编号最大的一张收藏图到输出目录,用于保持编号,否则会出现收藏的图片被覆盖的情况')\n img_list = os.listdir(f'{install_path}/stable-diffusion-webui/log/images')\n last_img_path = ''\n last_img_num = 0\n for img in img_list:\n if re.findall(r'^\\d+-',str(img)):\n num = int(re.findall(r'^\\d+-',str(img))[0][:-1])\n if num > last_img_num:\n last_img_path = img\n last_img_num = num\n print(f'{install_path}/stable-diffusion-webui/log/images/{last_img_path} {install_path}/stable-diffusion-webui/outputs/txt2img-images')\n !mkdir -p {install_path}/stable-diffusion-webui/outputs/txt2img-images\n !cp -f {install_path}/stable-diffusion-webui/log/images/{last_img_path} {install_path}/stable-diffusion-webui/outputs/txt2img-images/\n \n print(f'{install_path}/stable-diffusion-webui/log/images/{last_img_path} {install_path}/stable-diffusion-webui/outputs/img2img-images')\n !mkdir -p {install_path}/stable-diffusion-webui/outputs/img2img-images\n !cp -f {install_path}/stable-diffusion-webui/log/images/{last_img_path} {install_path}/stable-diffusion-webui/outputs/img2img-images/\n \n \ndef start_webui(i):\n # 只要不爆内存,其他方式关闭后会再次重启 访问地址会发生变化\n print(i,'--port',str(webuiPort+1+i))\n if i>0:\n print(f'使用第{i+1}张显卡启动第{i+1}个webui,通过frpc或nrgok地址后加/{i}/进行访问(不能使用同一个浏览器)')\n if useFrpc:\n while True:\n !venv/bin/python3 launch.py --device-id={i} --port {str(webuiPort+1+i)} {'' if i ==0 else '--nowebui'} # {'' if i == 0 else '--subpath=/'+str(i)}\n print('5秒后重启webui')\n time.sleep(5)\n else:\n !venv/bin/python3 launch.py --device-id={i} --port {str(webuiPort+1+i)} {'' if i ==0 else '--nowebui'} # {'' if i == 0 else '--subpath=/'+str(i)}\n \n# 启动\ndef start():\n print('启动webui')\n %cd $install_path/stable-diffusion-webui\n args = '' # ' --port=' + str(webuiPort+1)\n if not disableShared:\n args += ' --share'\n if onlyApi:\n args += ' --nowebui'\n if ui_config_file is not None and ui_config_file != '' and Path(ui_config_file).exists(): # ui配置文件\n args += ' --ui-config-file=' + pathJoin(ui_config_file)\n if setting_file is not None and setting_file != '' and Path(setting_file).exists(): # 设置配置文件\n args += ' --ui-settings-file=' + pathJoin(setting_file)\n if not checkDefaultModel():\n print('默认模型文件不存在,请检查配置:'+usedCkpt)\n else:\n args += ' --ckpt='+ pathJoin(usedCkpt)\n if vaeHalf is False: \n args += ' --no-half-vae'\n if modelHalf is False:\n args += ' --no-half'\n if consoleProgressbars is False:\n args += ' --disable-console-progressbars'\n if consolePrompts is True:\n args += ' --enable-console-prompts'\n args += ' ' + otherArgs\n os.environ['COMMANDLINE_ARGS']=args\n !echo COMMANDLINE_ARGS=$COMMANDLINE_ARGS\n %env REQS_FILE=requirements.txt\n \n threads = []\n for i in range(torch.cuda.device_count()):\n thread = threading.Thread(target = start_webui, name='solo_start_webui_'+str(i), daemon=True,args=([i]))\n thread.start()\n threads.append(thread)\n while thread.is_alive() and not check_service('localhost',str(webuiPort+1+i)): # 当当前服务启动完成才允许退出此次循环\n time.sleep(10)\n time.sleep(5)\n for thread in threads:\n thread.join()","metadata":{"_kg_hide-input":true,"id":"GTjyBJihLCtE","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 入口函数\n---","metadata":{"id":"qLvsk8ByLCtF"}},{"cell_type":"code","source":"\n# 启动非webui相关的的内容,加快启动速度\ndef main():\n global envInstalled\n global extensionsDone\n global huggingface_is_init\n startTicks = time.time()\n isInstall = True if os.getenv('IsInstall','False') == 'True' else False\n if isInstall is False or reLoad: \n print('启动 安装webui和运行环境')\n install()\n link_dir()\n init_huggingface()\n if enableThread:\n threading.Thread(target = install_extensions,daemon=True, name='solo_install_extensions').start()\n threading.Thread(target = load_models,daemon=True).start()\n threading.Thread(target = install_dependencies,daemon=True, name='solo_install_dependencies').start()\n if huggingface_is_init:\n threading.Thread(target = download_huggingface_repo,daemon=True,\n args=([huggingface_repo]),\n kwargs={\"callback\":copy_last_log_to_images},\n name='solo_download_huggingface_repo').start()\n\n else:\n install_extensions()\n load_models()\n install_dependencies()\n if huggingface_is_init:\n download_huggingface_repo(huggingface_repo,callback=copy_last_log_to_images)\n t = 0\n while not envInstalled or not extensionsDone:\n if t%10==0:\n print('等待python环境和插件安装...')\n t = t+1\n time.sleep(1)\n use_config()\n installProxyExe()\n os.environ['IsInstall'] = 'True'\n else:\n envInstalled = True\n extensionsDone = True\n sys.stdout = sys_sys_stdout\n stop_solo_threads()\n localProxy()\n threading.Thread(target = startProxy, daemon=True, name='solo_startProxy').start()\n if init_huggingface():\n start_sync_log_to_huggingface(huggingface_repo)\n load_models(True)\n ticks = time.time()\n print(\"加载耗时:\",(ticks - startTicks),\"秒\")\n start()\n","metadata":{"_kg_hide-input":true,"id":"IOKjaMlcLCtF","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 执行区域\n---","metadata":{"id":"0oaCRs2gLCtF"}},{"cell_type":"code","source":"# 启动\n# reLoad = True\n# hidden_console_info = False\nsys.stdout = sys_sys_stdout\nmain()","metadata":{"_kg_hide-output":true,"id":"O3DR0DWHLCtF","scrolled":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 停止一些不必要的后台线程\nstop_solo_threads()","metadata":{"scrolled":true,"trusted":true},"execution_count":null,"outputs":[]}]}
|
|
|
|
| 1 |
+
{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.7.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# 这只是一个完整项目的一部分 不能运行的 \n- 可以从这个地址运行 [点击��开](https://www.kaggle.com/viyiviyi/sdwui-before)\n---","metadata":{"id":"6zE2QeUKLCtC"}},{"cell_type":"code","source":"from pathlib import Path\nimport os\nimport time\nimport re\nimport subprocess\nimport threading\nimport sys\nimport socket\n\ninstall_path=f\"{os.environ['HOME']}/sdwebui\" # 安装目录\noutput_path=f\"{os.environ['HOME']}/sdwebui/Output\" # 输出目录 如果使用google云盘 会在google云盘增加sdwebui/Output\ninput_path = '/kaggle/input' # 输入目录\n\ngoogle_drive = '' \n# 连接谷歌云\ntry:\n if useGooglrDrive:\n from google.colab import drive\n drive.mount(f'~/google_drive')\n google_drive = f\"{os.environ['HOME']}/google_drive/MyDrive\"\n output_path = f'{google_drive}/sdwebui/Output'\n input_path = f'{google_drive}/sdwebui/Input'\n !mkdir -p {input_path}\nexcept:\n useGooglrDrive = False\n\n!mkdir -p {install_path}\n!mkdir -p {output_path}\n\nos.environ['install_path'] = install_path\nos.environ['output_path'] = output_path\nos.environ['google_drive'] = google_drive\n\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 模型目录 文件名称:链接的方式指定文件名\nmodelDirs = []+[item.strip() for item in 模型列表.split('\\n') if item.strip() ]\n# vae列表\nmodelVaeDirs = []+[item.strip() for item in VAE列表.split('\\n') if item.strip()]\n# 此配置内的目录下所有文件将加载到hypernetworks文件夹\nhypernetworksModelDirs = []+[item.strip() for item in hypernetworks列表.split('\\n') if item.strip()] \n# 此配置内的目录下所有文件将加载到embeddings文件夹\nembeddingsModelDirs = [] +[item.strip() for item in embeddings列表.split('\\n') if item.strip()]\n# 此配置内的目录下所有文件将加载到Lora文件夹\nloraModelDirs = []+[item.strip() for item in Lora列表.split('\\n') if item.strip()] \n\nlyCORISModelDirs = []+[item.strip() for item in LyCORIS列表.split('\\n') if item.strip()] \n# controlNet插件模型列表\ncontrolNetModels=[] +[item.strip() for item in controlNet模型列表.split('\\n') if item.strip()]\n# 插件列表\nextensions=[]+[item.strip() for item in 插件列表.split('\\n') if item.strip()]\n# 配置文件链接\nlinkHypernetworksDir=False # 链接 hypernetworks 目录到输出目录\nlinkEmbeddingsDir=False # 链接 embeddings 目录到输出目录\nlinkTextual_inversionDir=False # 链接 textual_inversion 目录到输出目录 如果需要保存训练过程的产出文件时建议开启\n\nngrokTokenFile = os.path.join(input_path,'configs/ngrok_token.txt') # 非必填 存放ngrokToken的文件的路径\nfrpcConfigFile = os.path.join(input_path,'configs/frpc_koishi.ini') # 非必填 frp 配置文件\n# ss证书目录 下载nginx的版本,把pem格式改成crt格式\nfrpcSSLFFlies =[os.path.join(input_path,'configs/koishi_ssl')]+[item.strip() for item in frpSSL文件.split('\\n') if item.strip() ]\n# frpc 文件目录 如果目录不存在,会自动下载,也可以在数据集搜索 viyiviyi/utils 添加\nfrpcExePath = os.path.join(input_path,'utils-tools/frpc')\n# 其他需要加载的webui启动参数 写到【参数列表】这个配置去\notherArgs = ' '.join([item.strip() for item in 参数列表.split('\\n') if item.strip()])\n\nvenvPath = os.path.join(input_path,'sd-webui-venv/venv.tar.bak') # 安装好的python环境 sd-webui-venv是一个公开是数据集 可以搜索添加\n\n# 用于使用kaggle api的token文件 参考 https://www.kaggle.com/docs/api\n# 此文件用于自动上传koishi的相关配置 也可以用于保存重要的输出文件\nkaggleApiTokenFile = os.path.join(input_path,'configs/kaggle.json')","metadata":{"_kg_hide-input":true,"id":"i3LhnwYHLCtC","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 这下面的是用于初始化一些值或者环境变量的,轻易别改\nfrpcStartArg = ''\n\n!mkdir -p $install_path/configFiles\nif Path(frp配置文件或配置.strip()).exists():\n frpcConfigFile = frp配置文件或配置.strip()\nif not Path(frpcConfigFile).exists(): \n if frp配置文件或配置.strip().startswith('-f'):\n frpcStartArg = frp配置文件或配置.strip()\n else:\n useFrpc = False\nelse:\n os.system(f'cp -f {frpcConfigFile} {install_path}/configFiles/frpc_webui.ini')\n frpcConfigFile = f'{install_path}/configFiles/frpc_webui.ini'\n os.system(f'sed -i \"s/local_port = .*/local_port = {webuiPort}/g\" {frpcConfigFile}')\n frpcStartArg = f' -c {frpcConfigFile}'\n\nngrokToken=''\nif Path(ngrok配置或文件地址.strip()).exists():\n ngrokTokenFile = ngrok配置或文件地址.strip()\nif Path(ngrokTokenFile).exists():\n with open(ngrokTokenFile,encoding = \"utf-8\") as nkfile:\n ngrokToken = nkfile.readline()\nelif not ngrok配置或文件地址.strip().startswith('/'):\n ngrokToken=ngrok配置或文件地址.strip()\n \nif not Path(venvPath).exists():\n venvPath = os.path.join(input_path,'sd-webui-venv/venv.zip')","metadata":{"_kg_hide-input":true,"id":"a_GtG2ayLCtD","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# kaggle public API\n\n**不能使用%cd这种会改变当前工作目录的命令,会导致和其他线程冲突**\n\n---","metadata":{"id":"p0uS-BLULCtD"}},{"cell_type":"code","source":"# 安装kaggle的api token文件\ndef initKaggleConfig():\n if Path('~/.kaggle/kaggle.json').exists():\n return True\n if Path(kaggleApiTokenFile).exists():\n !mkdir -p ~/.kaggle/\n os.system('cp '+kaggleApiTokenFile+' ~/.kaggle/kaggle.json')\n !chmod 600 ~/.kaggle/kaggle.json\n return True\n print('缺少kaggle的apiToken文件,访问:https://www.kaggle.com/你的kaggle用户名/account 获取')\n return False\n\ndef getUserName():\n if not initKaggleConfig(): return\n import kaggle\n return kaggle.KaggleApi().read_config_file()['username']\n\ndef createOrUpdateDataSet(path:str,datasetName:str):\n if not initKaggleConfig(): return\n print('创建或更新数据集 '+datasetName)\n import kaggle\n os.system('mkdir -p $install_path/kaggle_cache')\n os.system('rm -rf $install_path/kaggle_cache/*')\n datasetDirPath = install_path+'/kaggle_cache/'+datasetName\n os.system('mkdir -p '+datasetDirPath)\n os.system('cp -f '+path+' '+datasetDirPath+'/')\n username = getUserName()\n print(\"kaggle username:\"+username)\n datasetPath = username+'/'+datasetName\n datasetList = kaggle.api.dataset_list(mine=True,search=datasetPath)\n print(datasetList)\n if len(datasetList) == 0 or datasetPath not in [str(d) for d in datasetList]: # 创建 create\n os.system('kaggle datasets init -p' + datasetDirPath)\n metadataFile = datasetDirPath+'/dataset-metadata.json'\n os.system('sed -i s/INSERT_TITLE_HERE/'+ datasetName + '/g ' + metadataFile)\n os.system('sed -i s/INSERT_SLUG_HERE/'+ datasetName + '/g ' + metadataFile)\n os.system('cat '+metadataFile)\n os.system('kaggle datasets create -p '+datasetDirPath)\n print('create database done')\n else:\n kaggle.api.dataset_metadata(datasetPath,datasetDirPath)\n kaggle.api.dataset_create_version(datasetDirPath, 'auto update',dir_mode='zip')\n print('upload database done')\n\ndef downloadDatasetFiles(datasetName:str,outputPath:str):\n if not initKaggleConfig(): return\n print('下载数据集文件 '+datasetName)\n import kaggle\n username = getUserName()\n datasetPath = username+'/'+datasetName\n datasetList = kaggle.api.dataset_list(mine=True,search=datasetPath)\n if datasetPath not in [str(d) for d in datasetList]:\n return False\n os.system('mkdir -p '+outputPath)\n kaggle.api.dataset_download_files(datasetPath,path=outputPath,unzip=True)\n return True\n\n","metadata":{"_kg_hide-input":true,"id":"m8FJi4j0LCtD","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 工具函数\n**不能使用%cd这种会改变当前工作目录的命令,会导致和其他线程冲突**\n\n---","metadata":{"id":"sswa04veLCtE"}},{"cell_type":"code","source":"# 绕过 os.systen 的限制执行命令\ndef run(shell:str,shellName=''):\n if shellName == '': shellName = str(time.time())\n !mkdir -p $install_path/run_cache\n with open(install_path+'/run_cache/run_cache.'+shellName+'.sh','w') as sh:\n sh.write(shell)\n !bash {install_path}/run_cache/run_cache.{shellName}.sh\n\n# 连接多个路径字符串 让路径在shell命令中能正常的执行\ndef pathJoin(*paths:str):\n pathStr = ''\n for p in paths:\n pathStr += '\"'+p+'\"'\n pathStr = '\"*\"'.join(pathStr.split('*'))\n pathStr = '\"$\"'.join(pathStr.split('$'))\n pathStr = '\"(\"'.join(pathStr.split('('))\n pathStr = '\")\"'.join(pathStr.split(')'))\n pathStr = '\"{\"'.join(pathStr.split('{'))\n pathStr = '\"}\"'.join(pathStr.split('}'))\n pathStr = re.sub(r'\"\"','',pathStr)\n pathStr = re.sub(r'\\*{2,}','\"',pathStr)\n pathStr = re.sub(r'/{2,}','/',pathStr)\n pathStr = re.sub(r'/\\./','/',pathStr)\n return pathStr\n\n# 判断路径是不是一个文件或者可能指向一些文件\ndef pathIsFile(path):\n if Path(path).is_file():\n return True\n if re.search(r'\\.(ckpt|safetensors|png|jpg|txt|pt|pth|json|yaml|\\*)$',path):\n return True\n return False\n\ndef echoToFile(content:str,path:str):\n with open(path,'w') as sh:\n sh.write(content)\n\n# ngrok\ndef startNgrok(ngrokToken:str,ngrokLocalPort:int):\n from pyngrok import conf, ngrok\n try:\n conf.get_default().auth_token = ngrokToken\n conf.get_default().monitor_thread = False\n ssh_tunnels = ngrok.get_tunnels(conf.get_default())\n if len(ssh_tunnels) == 0:\n ssh_tunnel = ngrok.connect(ngrokLocalPort)\n print('address:'+ssh_tunnel.public_url)\n else:\n print('address:'+ssh_tunnels[0].public_url)\n except:\n print('启动ngrok出错')\n \ndef startFrpc(name,configFile):\n run(f'''\ncd $install_path/frpc/\n$install_path/frpc/frpc {configFile}\n ''',name)\n \ndef installProxyExe():\n if useFrpc:\n print('安装frpc')\n !mkdir -p $install_path/frpc\n if Path(frpcExePath).exists():\n os.system(f'cp -f -n {frpcExePath} $install_path/frpc/frpc')\n else:\n !wget \"https://huggingface.co/datasets/ACCA225/Frp/resolve/main/frpc\" -O $install_path/frpc/frpc\n \n for ssl in frpcSSLFFlies:\n if Path(ssl).exists():\n os.system('cp -f -n '+pathJoin(ssl,'/*')+' $install_path/frpc/')\n !chmod +x $install_path/frpc/frpc\n !$install_path/frpc/frpc -v\n if useNgrok:\n %pip install pyngrok\n\ndef startProxy():\n if useNgrok:\n startNgrok(ngrokToken,webuiPort)\n if useFrpc:\n startFrpc('frpc_proxy',frpcStartArg)\n\n \ndef zipPath(path:str,zipName:str,format='tar'):\n if path.startswith('$install_path'):\n path = path.replace('$install_path',install_path)\n if path.startswith('$output_path'):\n path = path.replace('$install_path',output_path)\n if not path.startswith('/'):\n path = pathJoin(install_path,'/stable-diffusion-webui','/',path)\n if Path(path).exists():\n if 'tar' == format:\n os.system('tar -cf $output_path/'+ zipName +'.tar -C '+ path +' . ')\n elif 'gz' == format:\n os.system('tar -czf $output_path/'+ zipName +'.tar.gz -C '+ path +' . ')\n return\n print('指定的目录不存在:'+path)\n","metadata":{"_kg_hide-input":true,"id":"coqQvTSLLCtE","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport re\nimport requests\n\ndef download_file(url, filename, path):\n # 获取文件的真实文件名\n if not filename:\n with requests.get(url, stream=True) as r:\n if 'Content-Disposition' in r.headers:\n filename = r.headers['Content-Disposition'].split('filename=')[1].strip('\"')\n r.close()\n filename = re.sub(r'[\\\\/:*?\"<>|;]', '', filename)\n # 拼接文件的完整路径\n filepath = os.path.join(path, filename)\n # 判断文件是否已存在\n if os.path.exists(filepath):\n print(f'{filename} already exists in {path}')\n return\n # 下载文件\n with requests.get(url, stream=True) as r:\n r.raise_for_status()\n with open(filepath, 'wb') as f:\n for chunk in r.iter_content(chunk_size=8192):\n if chunk:\n f.write(chunk)\n print(f'{filename} has been downloaded to {path}')\n \n# 加入文件到下载列表\ndef putDownloadFile(url:str,distDir:str,file_name:str=None):\n if re.match(r'^[^:]+:(https?|ftps?)://', url, flags=0):\n file_name = re.findall(r'^[^:]+:',url)[0][:-1]\n url = url[len(file_name)+1:]\n if not re.match(r'^(https?|ftps?)://',url):\n return\n file_name = re.sub(r'\\s+','_',file_name or '')\n dir = str(hash(url)).replace('-','')\n down_dir = f'{install_path}/down_cache/{dir}'\n !mkdir -p {down_dir}\n return [url,file_name,distDir,down_dir]\n\ndef get_file_size_in_gb(file_path):\n size_in_bytes = Path(file_path).stat().st_size\n size_in_gb = size_in_bytes / (1024 ** 3)\n return '%.2f' % size_in_gb\n \n# 下载文件\ndef startDownloadFiles(download_list):\n print('下载列表:\\n','\\n'.join([f'{item[0]} -> {item[2]}/{item[1]}' for item in download_list]))\n dist_list = []\n for dow_f in download_list:\n !mkdir -p {dow_f[3]}\n print('下载 名称:',dow_f[1],'url:',dow_f[0])\n download_file(dow_f[0],dow_f[1],dow_f[2])","metadata":{"_kg_hide-input":true,"id":"THNUsEm_LCtE","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n# nginx 反向代理配置文件\ndef localProxy():\n conf = '''\nserver\n{\n listen '''+str(webuiPort)+''';\n listen [::]:'''+str(webuiPort)+''';\n server_name 127.0.0.1 localhost 0.0.0.0 \"\";\n location /\n {\n proxy_pass http://127.0.0.1:'''+str(webuiPort+1)+'''/;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header REMOTE-HOST $remote_addr;\n proxy_set_header Upgrade $http_upgrade;\n proxy_set_header Connection upgrade;\n proxy_http_version 1.1;\n }\n location /1/\n {\n proxy_pass http://127.0.0.1:'''+str(webuiPort+2)+'''/;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header REMOTE-HOST $remote_addr;\n proxy_set_header Upgrade $http_upgrade;\n proxy_set_header Connection upgrade;\n proxy_http_version 1.1;\n }\n location /2/\n {\n proxy_pass http://127.0.0.1:'''+str(webuiPort+3)+'''/;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header REMOTE-HOST $remote_addr;\n proxy_set_header Upgrade $http_upgrade;\n proxy_set_header Connection upgrade;\n proxy_http_version 1.1;\n }\n location /3/\n {\n proxy_pass http://127.0.0.1:'''+str(webuiPort+4)+'''/;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header REMOTE-HOST $remote_addr;\n proxy_set_header Upgrade $http_upgrade;\n proxy_set_header Connection upgrade;\n proxy_http_version 1.1;\n }\n location /4/\n {\n proxy_pass http://127.0.0.1:'''+str(webuiPort+5)+'''/;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header REMOTE-HOST $remote_addr;\n proxy_set_header Upgrade $http_upgrade;\n proxy_set_header Connection upgrade;\n proxy_http_version 1.1;\n }\n}\n '''\n echoToFile(conf,'/etc/nginx/conf.d/proxy_nginx.conf')\n !nginx -c /etc/nginx/nginx.conf\n !nginx -s reload\n ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import inspect\nimport ctypes\n\ndef _async_raise(tid, exctype):\n \"\"\"raises the exception, performs cleanup if needed\"\"\"\n tid = ctypes.c_long(tid)\n if not inspect.isclass(exctype):\n exctype = type(exctype)\n res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))\n if res == 0:\n raise ValueError(\"invalid thread id\")\n elif res != 1:\n # \"\"\"if it returns a number greater than one, you're in trouble,\n # and you should call it again with exc=NULL to revert the effect\"\"\"\n ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)\n raise SystemError(\"PyThreadState_SetAsyncExc failed\")\n\ndef stop_thread(thread):\n _async_raise(thread.ident, SystemExit)\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# webui 安装和配置函数\n---","metadata":{"id":"Ve3p8oOkLCtE"}},{"cell_type":"code","source":"envInstalled=False\nextensionsDone=False\n\n#安装webui\ndef install():\n print('安装webui')\n %cd $install_path\n if reLoad:\n !rm -rf stable-diffusion-webui\n if Path(\"stable-diffusion-webui\").exists():\n %cd $install_path/stable-diffusion-webui/\n !git checkout .\n !git pull\n else:\n if mobileOptimize:\n !git clone https://github.com/viyiviyi/stable-diffusion-webui.git stable-diffusion-webui -b local # 修改了前端界面,手机使用更方便\n else:\n !git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui stable-diffusion-webui\n print('安装webui 完成')\n\n# 链接输出目录\ndef link_dir():\n print('链接输出目录')\n # 链接输出目录 因为sd被部署在了stable-diffusion-webui目录,运行结束后为了方便下载就只有outputs目录放在output_path/目录下\n !mkdir -p $output_path/outputs\n !rm -rf $install_path/stable-diffusion-webui/outputs\n !ln -s -r $output_path/outputs $install_path/stable-diffusion-webui/ # 输出目录\n !mkdir -p $output_path/log\n !rm -rf $install_path/stable-diffusion-webui/log\n !ln -s -r $output_path/log $install_path/stable-diffusion-webui/\n # 链接 hypernetworks 目录\n if linkHypernetworksDir:\n !rm -rf $install_path/stable-diffusion-webui/models/hypernetworks\n !mkdir -p $output_path/hypernetworks\n !ln -s -r $output_path/hypernetworks $install_path/stable-diffusion-webui/models/\n # 链接 embeddings 目录\n if linkEmbeddingsDir:\n !rm -rf $install_path/stable-diffusion-webui/embeddings\n !mkdir -p $output_path/embeddings\n !ln -s -r $output_path/embeddings $install_path/stable-diffusion-webui/\n # 链接训练输出目录 文件夹链接会导致功能不能用\n if linkTextual_inversionDir:\n !rm -rf $install_path/stable-diffusion-webui/textual_inversion\n !mkdir -p $output_path/textual_inversion/\n !ln -s -r $output_path/textual_inversion $install_path/stable-diffusion-webui/\n print('链接输出目录 完成')\n \n# 链接模型文件\ndef load_models(skip_url=False):\n print(('复制' if enableLoadByCopy else '链接') + '模型文件')\n if enableLoadByCopy:\n print('如果出现 No such file or directory 错误,可以忽略')\n download_list = []\n models_dir_path = f'{install_path}/stable-diffusion-webui/models/Stable-diffusion'\n hypernetworks_dir_path = f'{install_path}/stable-diffusion-webui/models/hypernetworks'\n embeddings_dir_path = f'{install_path}/stable-diffusion-webui/models/embeddings'\n lora_dir_path = f'{install_path}/stable-diffusion-webui/models/Lora'\n lycoris_dir_path = f'{install_path}/stable-diffusion-webui/models/LyCORIS'\n vae_dir_path = f'{install_path}/stable-diffusion-webui/models/VAE'\n control_net_dir_path = f'{install_path}/stable-diffusion-webui/extensions/sd-webui-controlnet/models'\n \n def link_file(source_paths,dist:str):\n !mkdir -p {dist}\n for path in source_paths:\n if 'https://' in path or 'http://' in path:\n if skip_url:\n continue\n download_list.append(putDownloadFile(path,dist))\n elif pathIsFile(path):\n os.system(('cp -n' if enableLoadByCopy else 'ln -s')+' -f '+ pathJoin(path) +f' {dist}')\n else:\n os.system(('cp -n' if enableLoadByCopy else 'ln -s')+' -f '+ pathJoin(path,'/*.*') +f' {dist}')\n !rm -f {dist}/\\*.* \n \n link_file(modelDirs,models_dir_path)\n link_file(hypernetworksModelDirs,hypernetworks_dir_path)\n link_file(embeddingsModelDirs,embeddings_dir_path)\n link_file(loraModelDirs,lora_dir_path)\n link_file(lyCORISModelDirs,lycoris_dir_path)\n link_file(modelVaeDirs,vae_dir_path)\n link_file(controlNetModels,control_net_dir_path)\n startDownloadFiles([item for item in download_list if item])\n print(('复制' if enableLoadByCopy else '链接') + '模型文件 完成')\n\n#安装依赖\ndef install_dependencies():\n print('安装webui需要的python环境')\n global envInstalled\n global venvPath\n !sudo apt install nginx -y\n sh = f'cd {install_path}/stable-diffusion-webui\\n'\n if str(sys.version).startswith('3.8') or str(sys.version).startswith('3.9') or str(sys.version).startswith('3.10'):\n sh += '''\npython3 -m venv venv\n'''\n else:\n sh += '''\nadd-apt-repository ppa:deadsnakes/ppa -y\napt update\napt install python3.10 -y\npython3.10 -m venv venv\n'''\n if quickStart:\n if not Path(venvPath).exists():\n !mkdir -p {install_path}/venv_cache\n if not Path(f'{install_path}/venv_cache/venv.tar.bak').exists():\n download_file('https://huggingface.co/viyi/sdwui/resolve/main/venv.zip','venv.zip',f'{install_path}/venv_cache')\n !unzip {install_path}/venv_cache/venv.zip -d {install_path}/venv_cache\n venvPath = f'{install_path}/venv_cache/venv.tar.bak'\n !rm -rf {install_path}/venv_cache/venv.zip\n elif venvPath.endswith('.zip'):\n !mkdir -p {install_path}/venv_cache\n !unzip {venvPath} -d {install_path}/venv_cache\n venvPath = f'{install_path}/venv_cache/venv.tar.bak'\n \n sh += 'echo \"unzip venv\"\\n'\n sh += f'tar -xf {venvPath} -C ./venv\\n'\n sh += '\\n'\n run(sh,'dependencies')\n if not Path(f'{install_path}/stable-diffusion-webui/venv/bin/pip').exists():\n !curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py\n !{install_path}/stable-diffusion-webui/venv/bin/python3 get-pip.py\n \n !{install_path}/stable-diffusion-webui/venv/bin/python3 -V\n !{install_path}/stable-diffusion-webui/venv/bin/python3 -m pip -V\n \n if not quickStart or not Path(venvPath).exists():\n !{install_path}/stable-diffusion-webui/venv/bin/python3 -m pip install -U torch==2.0.0+cu117 torchvision==0.15.1+cu117 torchaudio==2.0.1 --index-url https://download.pytorch.org/whl/cu117\n !{install_path}/stable-diffusion-webui/venv/bin/python3 -m pip install -U open-clip-torch xformers==0.0.19\n \n envInstalled = True\n print('安装webui需要的python环境 完成')\n\n# 安装插件\ndef install_extensions():\n global extensionsDone\n print('安装插件')\n sh = 'mkdir -p $install_path/stable-diffusion-webui/extensions \\n'\n sh = 'mkdir -p $install_path/cache/extensions \\n'\n sh += 'cd $install_path/cache/extensions \\n'\n for ex in extensions:\n sh += 'git clone ' + ex + ' \\n'\n sh += 'rsync -a $install_path/cache/extensions/* $install_path/stable-diffusion-webui/extensions \\n'\n sh += 'cd ../ && rm -rf $install_path/cache/extensions \\n'\n run(sh,'extensions')\n extensionsDone = True\n print('安装插件 完成')\n \n# 个性化配置 \ndef use_config():\n print('使用自定义配置 包括tag翻译 \\n')\n %cd $install_path/stable-diffusion-webui\n !mkdir -p tmp\n %cd tmp\n !git clone {webui_settings} sd-configs\n !cp -rf sd-configs/dist/* $install_path/stable-diffusion-webui\n if not Path(ui_config_file).exists(): # ui配置文件\n !mkdir -p {ui_config_file[0:ui_config_file.rfind('/')]}\n os.system('cp -f -n $install_path/stable-diffusion-webui/ui-config.json '+ui_config_file)\n if not Path(setting_file).exists(): # 设置配置文件\n !mkdir -p {setting_file[0:setting_file.rfind('/')]}\n os.system('cp -f -n $install_path/stable-diffusion-webui/config.json '+setting_file)\n\ndef checkDefaultModel():\n print('检查默认模型文件是否存在 \\n')\n global usedCkpt\n if usedCkpt is not None and usedCkpt != '': # 设置启动时默认加载的模型\n if '.' in usedCkpt:\n if '/' in usedCkpt:\n usedCkpt = usedCkpt\n else:\n usedCkpt = install_path + '/stable-diffusion-webui/models/Stable-diffusion/' + usedCkpt\n else:\n for x in ['.ckpt','.safetensors']:\n if Path(install_path+'/stable-diffusion-webui/models/Stable-diffusion/' + usedCkpt+x).exists():\n usedCkpt = install_path+'/stable-diffusion-webui/models/Stable-diffusion/' + usedCkpt+x\n break\n if Path(usedCkpt).exists():\n return True\n else:\n if Path(usedCkpt).is_symlink():\n print('模型文件真实地址:'+os.readlink(usedCkpt))\n return False\n \ndef check_service(host, port):\n try:\n socket.create_connection((host, port), timeout=5)\n return True\n except socket.error:\n return False\n \ndef start_webui(i):\n # 只要不爆内存,其他方式关闭后会再次重启 访问地址会发生变化\n print(i,'--port',str(webuiPort+1+i))\n if i>0:\n print(f'使用第{i+1}张显卡启动第{i+1}个webui,通过frpc或nrgok地址后加/{i}/进行访问')\n if useFrpc:\n while True:\n !venv/bin/python3 launch.py --device-id={i} --port {str(webuiPort+1+i)}\n print('5秒后重启webui')\n time.sleep(5)\n else:\n !venv/bin/python3 launch.py --device-id={i} --port {str(webuiPort+1+i)}\n \n# 启动\ndef start():\n print('启动webui')\n %cd $install_path/stable-diffusion-webui\n args = '' # ' --port=' + str(webuiPort+1)\n if not disableShared:\n args += ' --share'\n if onlyApi:\n args += ' --nowebui'\n if ui_config_file is not None and ui_config_file != '' and Path(ui_config_file).exists(): # ui配置文件\n args += ' --ui-config-file=' + pathJoin(ui_config_file)\n if setting_file is not None and setting_file != '' and Path(setting_file).exists(): # 设置配置文件\n args += ' --ui-settings-file=' + pathJoin(setting_file)\n if not checkDefaultModel():\n print('默认模型文件不存在,请检查配置:'+usedCkpt)\n else:\n args += ' --ckpt='+ pathJoin(usedCkpt)\n if vaeHalf is False: \n args += ' --no-half-vae'\n if modelHalf is False:\n args += ' --no-half'\n if consoleProgressbars is False:\n args += ' --disable-console-progressbars'\n if consolePrompts is True:\n args += ' --enable-console-prompts'\n args += ' ' + otherArgs\n os.environ['COMMANDLINE_ARGS']=args\n !echo COMMANDLINE_ARGS=$COMMANDLINE_ARGS\n %env REQS_FILE=requirements.txt\n import torch\n for i in range(torch.cuda.device_count()):\n threading.Thread(target = start_webui, name='solo_start_webui_'+str(i), daemon=True,args=([i])).start()\n while not check_service('localhost',str(webuiPort+1+i)): # 当当前服务启动完成才允许退出此次循环\n time.sleep(10)\n time.sleep(5)\n time.sleep(60*60*24)","metadata":{"_kg_hide-input":true,"id":"GTjyBJihLCtE","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 入口函数\n---","metadata":{"id":"qLvsk8ByLCtF"}},{"cell_type":"code","source":"\n# 启动非webui相关的的内容,加快启动速度\ndef main():\n global envInstalled\n global extensionsDone\n startTicks = time.time()\n isInstall = True if os.getenv('IsInstall','False') == 'True' else False\n if isInstall is False or reLoad: \n install()\n if enableThread:\n threading.Thread(target = install_extensions,daemon=True).start()\n threading.Thread(target = load_models,daemon=True).start()\n threading.Thread(target = install_dependencies,daemon=True).start()\n else:\n install_extensions()\n load_models()\n install_dependencies()\n t = 0\n while not envInstalled or not extensionsDone:\n if t%10==0:\n print('等待python环境和插件安装...')\n t = t+1\n time.sleep(1)\n link_dir()\n use_config()\n localProxy()\n installProxyExe()\n os.environ['IsInstall'] = 'True'\n else:\n envInstalled = True\n extensionsDone = True\n \n # 获取当前所有活动的线程\n threads = threading.enumerate()\n # 关闭之前创建的子线程\n for thread in threads:\n if thread.name.startswith('solo_'):\n print(thread.name)\n try:\n stop_thread(thread)\n except socket.error:\n print(f'结束进程:{thread.name} 执行失败')\n \n threading.Thread(target = startProxy, daemon=True, name='solo_startProxy').start()\n load_models(True)\n ticks = time.time()\n print(\"加载耗时:\",(ticks - startTicks),\"秒\")\n start()\n","metadata":{"_kg_hide-input":true,"id":"IOKjaMlcLCtF","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 执行区域\n---","metadata":{"id":"0oaCRs2gLCtF"}},{"cell_type":"code","source":"# 启动\nmain()","metadata":{"_kg_hide-output":true,"id":"O3DR0DWHLCtF","scrolled":true,"trusted":true},"execution_count":null,"outputs":[]}]}
|
sdwui_install.py
DELETED
|
@@ -1,734 +0,0 @@
|
|
| 1 |
-
#!/usr/bin/env python
|
| 2 |
-
# coding: utf-8
|
| 3 |
-
|
| 4 |
-
from pathlib import Path
|
| 5 |
-
import os
|
| 6 |
-
import time
|
| 7 |
-
import re
|
| 8 |
-
import subprocess
|
| 9 |
-
import threading
|
| 10 |
-
import sys
|
| 11 |
-
import socket
|
| 12 |
-
from typing import List
|
| 13 |
-
import config
|
| 14 |
-
|
| 15 |
-
def mkdirs(path, exist_ok=True):
|
| 16 |
-
if path and not Path(path).exists():
|
| 17 |
-
os.makedirs(path,exist_ok=exist_ok)
|
| 18 |
-
|
| 19 |
-
# 内置参数默认值,当上下文有参数时可覆盖默认值
|
| 20 |
-
|
| 21 |
-
_useFrpc = config.useFrpc
|
| 22 |
-
|
| 23 |
-
_useNgrok = config.useNgrok
|
| 24 |
-
|
| 25 |
-
_reLoad = config.reLoad
|
| 26 |
-
|
| 27 |
-
_before_downloading = config.before_downloading
|
| 28 |
-
|
| 29 |
-
_async_downloading = config.async_downloading
|
| 30 |
-
|
| 31 |
-
_before_start_sync_downloading = config.before_start_sync_downloading
|
| 32 |
-
|
| 33 |
-
_server_port = config.server_port or 7860
|
| 34 |
-
|
| 35 |
-
_sd_git_repo = config.sd_git_repo\
|
| 36 |
-
.replace('{sdwui}','stable-diffusion-webui')\
|
| 37 |
-
.replace('{wui}',"webui") or 'https://github.com/viyiviyi/stable-diffusion-webui.git -b local'
|
| 38 |
-
|
| 39 |
-
_sd_config_git_repu = config.sd_config_git_repu\
|
| 40 |
-
.replace('{sdwui}','stable-diffusion-webui')\
|
| 41 |
-
.replace('{wui}',"webui") or 'https://github.com/viyiviyi/sd-configs.git'
|
| 42 |
-
|
| 43 |
-
_link_instead_of_copy = config.link_instead_of_copy
|
| 44 |
-
|
| 45 |
-
show_shell_info = not config.hidden_console_info
|
| 46 |
-
|
| 47 |
-
_skip_start = config.skip_start
|
| 48 |
-
|
| 49 |
-
run_by_none_device = False
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
def run(command, cwd=None, desc=None, errdesc=None, custom_env=None,try_error:bool=True) -> str:
|
| 53 |
-
global show_shell_info
|
| 54 |
-
if desc is not None:
|
| 55 |
-
print(desc)
|
| 56 |
-
|
| 57 |
-
run_kwargs = {
|
| 58 |
-
"args": command,
|
| 59 |
-
"shell": True,
|
| 60 |
-
"cwd": cwd,
|
| 61 |
-
"env": os.environ if custom_env is None else custom_env,
|
| 62 |
-
"encoding": 'utf8',
|
| 63 |
-
"errors": 'ignore',
|
| 64 |
-
}
|
| 65 |
-
|
| 66 |
-
if not show_shell_info:
|
| 67 |
-
run_kwargs["stdout"] = run_kwargs["stderr"] = subprocess.PIPE
|
| 68 |
-
|
| 69 |
-
result = subprocess.run(**run_kwargs)
|
| 70 |
-
|
| 71 |
-
if result.returncode != 0:
|
| 72 |
-
error_bits = [
|
| 73 |
-
f"{errdesc or 'Error running command'}.",
|
| 74 |
-
f"Command: {command}",
|
| 75 |
-
f"Error code: {result.returncode}",
|
| 76 |
-
]
|
| 77 |
-
if result.stdout:
|
| 78 |
-
error_bits.append(f"stdout: {result.stdout}")
|
| 79 |
-
if result.stderr:
|
| 80 |
-
error_bits.append(f"stderr: {result.stderr}")
|
| 81 |
-
if try_error:
|
| 82 |
-
print(RuntimeError("\n".join(error_bits)))
|
| 83 |
-
else:
|
| 84 |
-
raise RuntimeError("\n".join(error_bits))
|
| 85 |
-
|
| 86 |
-
if show_shell_info:
|
| 87 |
-
print(result.stdout or "")
|
| 88 |
-
return (result.stdout or "")
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
install_path=f"{os.getcwd()}/sdwui" # 安装目录
|
| 92 |
-
output_path= os.path.join(os.getcwd(), config.output_path or 'sdwui/Output')
|
| 93 |
-
input_path = config.input_path or f'{os.getcwd()}/sdwui/Input'
|
| 94 |
-
|
| 95 |
-
mkdirs(install_path,True)
|
| 96 |
-
mkdirs(output_path,True)
|
| 97 |
-
|
| 98 |
-
os.environ['install_path'] = install_path
|
| 99 |
-
os.environ['output_path'] = output_path
|
| 100 |
-
os.environ['input_path'] = input_path
|
| 101 |
-
|
| 102 |
-
def replace_path(input_str:str):
|
| 103 |
-
return input_str.replace('$install_path',install_path)\
|
| 104 |
-
.replace('{install_path}',install_path)\
|
| 105 |
-
.replace('$input_path',input_path)\
|
| 106 |
-
.replace('{input_path}',input_path)\
|
| 107 |
-
.replace('$output_path',output_path)\
|
| 108 |
-
.replace('{output_path}',output_path)\
|
| 109 |
-
.replace('{sdwui}','stable-diffusion-webui')\
|
| 110 |
-
.replace('{wui}',"webui")
|
| 111 |
-
|
| 112 |
-
space_string = ' \n\r\t\'\",'
|
| 113 |
-
|
| 114 |
-
def config_reader(conf:str):
|
| 115 |
-
args = [replace_path(item.split('#')[0].strip(space_string)) for item in conf.split('\n') if item.strip(space_string)]
|
| 116 |
-
return [item.strip() for item in args if item.strip()]
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
ngrokTokenFile = os.path.join(input_path,'configs/ngrok_token.txt') # 非必填 存放ngrokToken的文件的路径
|
| 120 |
-
frpcConfigFile = os.path.join(input_path,'configs/frpc_koishi.ini') # 非必填 frp 配置文件
|
| 121 |
-
# ss证书目录 下载nginx的版本,把pem格式改成crt格式
|
| 122 |
-
frpcSSLFFlies = [os.path.join(input_path,'configs/koishi_ssl')] + config_reader(config.frp_ssl_dir)
|
| 123 |
-
|
| 124 |
-
# frpc 文件目录 如果目录不存在,会自动下载,也可以在数据集搜索 viyiviyi/utils 添加
|
| 125 |
-
frpcExePath = os.path.join(input_path,'utils-tools/frpc')
|
| 126 |
-
# 其他需要加载的webui启动参数 写到【参数列表】这个配置去
|
| 127 |
-
otherArgs = ' '.join([item for item in config_reader(config.sd_start_args) if item != '--no-gradio-queue']) or '--xformers'
|
| 128 |
-
|
| 129 |
-
venvPath = os.path.join(input_path,'sd-webui-venv/venv.tar.bak') # 安装好的python环境 sd-webui-venv是一个公开是数据集 可以搜索添加
|
| 130 |
-
|
| 131 |
-
# 用于使用kaggle api的token文件 参考 https://www.kaggle.com/docs/api
|
| 132 |
-
# 此文件用于自动上传koishi的相关配置 也可以用于保存重要的输出文件
|
| 133 |
-
kaggleApiTokenFile = os.path.join(input_path,'configs/kaggle.json')
|
| 134 |
-
|
| 135 |
-
requirements = []
|
| 136 |
-
|
| 137 |
-
frpcStartArg = ''
|
| 138 |
-
|
| 139 |
-
_setting_file = replace_path(config.setting_file)
|
| 140 |
-
|
| 141 |
-
_ui_config_file = replace_path(config.ui_config_file)
|
| 142 |
-
|
| 143 |
-
mkdirs(f'{install_path}/configFiles',True)
|
| 144 |
-
|
| 145 |
-
_frp_config_or_file = replace_path(config.frp_config_or_file)
|
| 146 |
-
if Path(_frp_config_or_file.strip()).exists():
|
| 147 |
-
frpcConfigFile = _frp_config_or_file.strip()
|
| 148 |
-
if not Path(frpcConfigFile).exists():
|
| 149 |
-
if _frp_config_or_file.strip().startswith('-f'):
|
| 150 |
-
frpcStartArg = _frp_config_or_file.strip()
|
| 151 |
-
else:
|
| 152 |
-
print('没有frpcp配置')
|
| 153 |
-
_useFrpc = False
|
| 154 |
-
else:
|
| 155 |
-
run(f'''cp -f {frpcConfigFile} {install_path}/configFiles/frpc_webui.ini''')
|
| 156 |
-
frpcConfigFile = f'{install_path}/configFiles/frpc_webui.ini'
|
| 157 |
-
run(f'''sed -i "s/local_port = .*/local_port = {_server_port}/g" {frpcConfigFile}''')
|
| 158 |
-
frpcStartArg = f' -c {frpcConfigFile}'
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
ngrokToken=''
|
| 162 |
-
_ngrok_config_or_file = replace_path(config.ngrok_config_or_file)
|
| 163 |
-
if Path(_ngrok_config_or_file.strip()).exists():
|
| 164 |
-
ngrokTokenFile = _ngrok_config_or_file.strip()
|
| 165 |
-
if Path(ngrokTokenFile).exists():
|
| 166 |
-
with open(ngrokTokenFile,encoding = "utf-8") as nkfile:
|
| 167 |
-
ngrokToken = nkfile.readline()
|
| 168 |
-
elif not _ngrok_config_or_file.strip().startswith('/'):
|
| 169 |
-
ngrokToken=_ngrok_config_or_file.strip()
|
| 170 |
-
|
| 171 |
-
if not Path(venvPath).exists():
|
| 172 |
-
venvPath = os.path.join(input_path,'sd-webui-venv/venv.zip')
|
| 173 |
-
|
| 174 |
-
import concurrent.futures
|
| 175 |
-
import importlib
|
| 176 |
-
import os
|
| 177 |
-
import pprint
|
| 178 |
-
import re
|
| 179 |
-
from pathlib import Path
|
| 180 |
-
from typing import List
|
| 181 |
-
|
| 182 |
-
import requests
|
| 183 |
-
|
| 184 |
-
show_shell_info = False
|
| 185 |
-
|
| 186 |
-
|
| 187 |
-
def is_installed(package):
|
| 188 |
-
try:
|
| 189 |
-
spec = importlib.util.find_spec(package)
|
| 190 |
-
except ModuleNotFoundError:
|
| 191 |
-
return False
|
| 192 |
-
|
| 193 |
-
return spec is not None
|
| 194 |
-
|
| 195 |
-
def download_file(url:str, filename:str, dist_path:str, cache_path = '',_link_instead_of_copy:bool=True):
|
| 196 |
-
# 获取文件的真实文件名
|
| 197 |
-
if not filename:
|
| 198 |
-
with requests.get(url, stream=True) as r:
|
| 199 |
-
if 'Content-Disposition' in r.headers:
|
| 200 |
-
filename = r.headers['Content-Disposition'].split('filename=')[1].strip('"')
|
| 201 |
-
r.close()
|
| 202 |
-
if not filename and re.search(r'/[^/]+\.[^/]+$',url):
|
| 203 |
-
filename = url.split('/')[-1]
|
| 204 |
-
|
| 205 |
-
filename = re.sub(r'[\\/:*?"<>|;]', '', filename)
|
| 206 |
-
filename = re.sub(r'[\s\t]+', '_', filename)
|
| 207 |
-
|
| 208 |
-
if show_shell_info:
|
| 209 |
-
print(f'下载 {filename} url: {url} --> {dist_path}')
|
| 210 |
-
|
| 211 |
-
# 创建目录
|
| 212 |
-
if cache_path and not Path(cache_path).exists():
|
| 213 |
-
mkdirs(cache_path,exist_ok=True)
|
| 214 |
-
if dist_path and not Path(dist_path).exists():
|
| 215 |
-
mkdirs(dist_path,exist_ok=True)
|
| 216 |
-
|
| 217 |
-
# 拼接文件的完整路径
|
| 218 |
-
filepath = os.path.join(dist_path, filename)
|
| 219 |
-
|
| 220 |
-
if cache_path:
|
| 221 |
-
cache_path = os.path.join(cache_path, filename)
|
| 222 |
-
|
| 223 |
-
# 判断文件是否已存在
|
| 224 |
-
if Path(filepath).exists():
|
| 225 |
-
print(f'文件 {filename} 已存在 {dist_path}')
|
| 226 |
-
return
|
| 227 |
-
|
| 228 |
-
if cache_path and Path(cache_path).exists():
|
| 229 |
-
run(f'cp -n -r -f {"-s" if _link_instead_of_copy else ""} {cache_path} {dist_path}')
|
| 230 |
-
if show_shell_info:
|
| 231 |
-
print(f'文件缓存 {cache_path} --> {dist_path}')
|
| 232 |
-
return
|
| 233 |
-
# 下载文件
|
| 234 |
-
with requests.get(url, stream=True) as r:
|
| 235 |
-
r.raise_for_status()
|
| 236 |
-
with open(cache_path or filepath, 'wb') as f:
|
| 237 |
-
for chunk in r.iter_content(chunk_size=8192):
|
| 238 |
-
if chunk:
|
| 239 |
-
f.write(chunk)
|
| 240 |
-
# 如果使用了缓存目录 需要复制或链接文件到目标目录
|
| 241 |
-
if cache_path:
|
| 242 |
-
run(f'cp -n -r -f {"-s" if _link_instead_of_copy else ""} {cache_path} {dist_path}')
|
| 243 |
-
if show_shell_info:
|
| 244 |
-
print(f'下载完成 {filename} --> {dist_path}')
|
| 245 |
-
|
| 246 |
-
def download_git(url, dist_path, cache_path = '',_link_instead_of_copy:bool=True):
|
| 247 |
-
if not Path(dist_path).exists():
|
| 248 |
-
mkdirs(dist_path,exist_ok=True)
|
| 249 |
-
if show_shell_info:
|
| 250 |
-
print(f'git 下载 {url} --> {dist_path}')
|
| 251 |
-
if cache_path and not Path(cache_path).exists():
|
| 252 |
-
mkdirs(cache_path,exist_ok=True)
|
| 253 |
-
run(f'git clone {config.git_proxy}{url}',cwd = cache_path)
|
| 254 |
-
if cache_path:
|
| 255 |
-
run(f'cp -n -r -f {cache_path}/* {dist_path}')
|
| 256 |
-
else:
|
| 257 |
-
run(f'git clone {config.git_proxy}{url}',cwd = dist_path)
|
| 258 |
-
if show_shell_info:
|
| 259 |
-
print(f'git 下载完成 {url} --> {dist_path}')
|
| 260 |
-
|
| 261 |
-
|
| 262 |
-
|
| 263 |
-
# 加入文件到下载列表
|
| 264 |
-
def pause_url(url:str,dist_path:str):
|
| 265 |
-
file_name = ''
|
| 266 |
-
if re.match(r'^[^:]+:(https?|ftps?)://', url, flags=0):
|
| 267 |
-
file_name = re.findall(r'^[^:]+:',url)[0][:-1]
|
| 268 |
-
url = url[len(file_name)+1:]
|
| 269 |
-
if not re.match(r'^(https?|ftps?)://',url):
|
| 270 |
-
return
|
| 271 |
-
file_name = re.sub(r'\s+','_',file_name or '')
|
| 272 |
-
path_hash = str(hash(url)).replace('-','')
|
| 273 |
-
|
| 274 |
-
return {'file_name':file_name,'path_hash':path_hash,'url':url,'dist_path':dist_path}
|
| 275 |
-
|
| 276 |
-
def download_urls(download_list:List[dict],sync:bool=False,thread_num:int=5,
|
| 277 |
-
cache_path:str=os.path.join(os.getcwd(),'.cache','download_util'),
|
| 278 |
-
_link_instead_of_copy:bool=True,is_await:bool=False):
|
| 279 |
-
if sync:
|
| 280 |
-
for conf in download_list:
|
| 281 |
-
cache_dir = os.path.join(cache_path,conf['path_hash'])
|
| 282 |
-
if conf['url'].startswith('https://github.com'):
|
| 283 |
-
download_git(conf['url'],conf['dist_path'],cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy)
|
| 284 |
-
continue
|
| 285 |
-
download_file(conf['url'],conf['file_name'],conf['dist_path'],cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy)
|
| 286 |
-
else:
|
| 287 |
-
executor = concurrent.futures.ThreadPoolExecutor(max_workers=thread_num)
|
| 288 |
-
futures = []
|
| 289 |
-
for conf in download_list:
|
| 290 |
-
cache_dir = os.path.join(cache_path,conf['path_hash'])
|
| 291 |
-
if conf['url'].startswith('https://github.com'):
|
| 292 |
-
futures.append(executor.submit(download_git, conf['url'],conf['dist_path'],
|
| 293 |
-
cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy))
|
| 294 |
-
continue
|
| 295 |
-
futures.append(executor.submit(download_file, conf['url'],conf['file_name'],conf['dist_path'],
|
| 296 |
-
cache_path=cache_dir,_link_instead_of_copy=_link_instead_of_copy))
|
| 297 |
-
if is_await:
|
| 298 |
-
concurrent.futures.wait(futures)
|
| 299 |
-
|
| 300 |
-
|
| 301 |
-
def parse_config(config:str):
|
| 302 |
-
space_string = ' \n\r\t\'\",'
|
| 303 |
-
other_flie_list = [item.split('#')[0].strip(space_string) for item in config.split('\n') if item.strip(space_string)]
|
| 304 |
-
other_flie_list = [item.strip() for item in other_flie_list if item.strip()]
|
| 305 |
-
other_flie_list_store = {}
|
| 306 |
-
other_flie_list_store_name='default'
|
| 307 |
-
other_flie_list_store_list_cache=[]
|
| 308 |
-
|
| 309 |
-
for item in other_flie_list:
|
| 310 |
-
if item.startswith('[') and item.endswith(']'):
|
| 311 |
-
if not other_flie_list_store_name == 'default':
|
| 312 |
-
other_flie_list_store[other_flie_list_store_name]=other_flie_list_store_list_cache
|
| 313 |
-
other_flie_list_store_list_cache = []
|
| 314 |
-
other_flie_list_store_name = item[1:-1]
|
| 315 |
-
else:
|
| 316 |
-
other_flie_list_store_list_cache.append(item)
|
| 317 |
-
other_flie_list_store[other_flie_list_store_name]=other_flie_list_store_list_cache
|
| 318 |
-
|
| 319 |
-
return other_flie_list_store
|
| 320 |
-
|
| 321 |
-
|
| 322 |
-
def link_or_download_flie(config:str, skip_url:bool=False, _link_instead_of_copy:bool=True, base_path:str = '',
|
| 323 |
-
sync:bool=False,thread_num:int=None, is_await:bool=False):
|
| 324 |
-
store:dict[str,List[str]] = parse_config(config)
|
| 325 |
-
download_list = []
|
| 326 |
-
for dist_dir in store.keys():
|
| 327 |
-
dist_path = os.path.join(base_path,dist_dir)
|
| 328 |
-
mkdirs(dist_path,exist_ok=True)
|
| 329 |
-
for path in store[dist_dir]:
|
| 330 |
-
if 'https://' in path or 'http://' in path:
|
| 331 |
-
if skip_url:
|
| 332 |
-
continue
|
| 333 |
-
if sync:
|
| 334 |
-
download_urls([pause_url(path,dist_path)],_link_instead_of_copy = _link_instead_of_copy, sync=sync)
|
| 335 |
-
continue
|
| 336 |
-
download_list.append(pause_url(path,dist_path))
|
| 337 |
-
else:
|
| 338 |
-
run(f'cp -n -r -f {"-s" if _link_instead_of_copy else ""} {path} {dist_path}')
|
| 339 |
-
if show_shell_info:
|
| 340 |
-
print(f'{"链接" if _link_instead_of_copy else "复制"} {path} --> {dist_path}')
|
| 341 |
-
run(f'rm -f {dist_path}/\*.* ')
|
| 342 |
-
if not skip_url:
|
| 343 |
-
if show_shell_info:
|
| 344 |
-
pprint.pprint(download_list)
|
| 345 |
-
download_urls(download_list,_link_instead_of_copy = _link_instead_of_copy, sync=sync, thread_num=thread_num or 2,is_await=is_await)
|
| 346 |
-
|
| 347 |
-
|
| 348 |
-
def echoToFile(content:str,path:str):
|
| 349 |
-
if path.find('/') >= 0:
|
| 350 |
-
_path = '/'.join(path.split('/')[:-1])
|
| 351 |
-
mkdirs(f'{_path}',True)
|
| 352 |
-
with open(path,'w') as sh:
|
| 353 |
-
sh.write(content)
|
| 354 |
-
|
| 355 |
-
def zipPath(path:str,zipName:str,format='tar'):
|
| 356 |
-
if path.startswith('$install_path'):
|
| 357 |
-
path = path.replace('$install_path',install_path)
|
| 358 |
-
if path.startswith('$output_path'):
|
| 359 |
-
path = path.replace('$install_path',output_path)
|
| 360 |
-
if not path.startswith('/'):
|
| 361 |
-
path = f'{install_path}/sd_main_dir/{path}'
|
| 362 |
-
if Path(path).exists():
|
| 363 |
-
if 'tar' == format:
|
| 364 |
-
run(f'tar -cf {output_path}/'+ zipName +'.tar -C '+ path +' . ')
|
| 365 |
-
elif 'gz' == format:
|
| 366 |
-
run(f'tar -czf {output_path}/'+ zipName +'.tar.gz -C '+ path +' . ')
|
| 367 |
-
return
|
| 368 |
-
print('指定的目录不存在:'+path)
|
| 369 |
-
|
| 370 |
-
# 检查网络
|
| 371 |
-
def check_service(host, port):
|
| 372 |
-
try:
|
| 373 |
-
socket.create_connection((host, port), timeout=5)
|
| 374 |
-
return True
|
| 375 |
-
except socket.error:
|
| 376 |
-
return False
|
| 377 |
-
|
| 378 |
-
# ngrok
|
| 379 |
-
def startNgrok(ngrokToken:str,ngrokLocalPort:int):
|
| 380 |
-
if not is_installed('pyngrok'):
|
| 381 |
-
run(f'pip install pyngrok')
|
| 382 |
-
from pyngrok import conf, ngrok
|
| 383 |
-
try:
|
| 384 |
-
conf.get_default().auth_token = ngrokToken
|
| 385 |
-
conf.get_default().monitor_thread = False
|
| 386 |
-
ssh_tunnels = ngrok.get_tunnels(conf.get_default())
|
| 387 |
-
if len(ssh_tunnels) == 0:
|
| 388 |
-
ssh_tunnel = ngrok.connect(ngrokLocalPort)
|
| 389 |
-
print('ngrok 访问地址:'+ssh_tunnel.public_url)
|
| 390 |
-
else:
|
| 391 |
-
print('ngrok 访问地址:'+ssh_tunnels[0].public_url)
|
| 392 |
-
except:
|
| 393 |
-
print('启动ngrok出错')
|
| 394 |
-
|
| 395 |
-
def startFrpc(name,configFile):
|
| 396 |
-
echoToFile(f'''
|
| 397 |
-
cd {install_path}/frpc/
|
| 398 |
-
{install_path}/frpc/frpc {configFile}
|
| 399 |
-
''',f'{install_path}/frpc/start.sh')
|
| 400 |
-
os.system(f'''bash {install_path}/frpc/start.sh''')
|
| 401 |
-
|
| 402 |
-
def installProxyExe():
|
| 403 |
-
if _useFrpc:
|
| 404 |
-
print('安装frpc')
|
| 405 |
-
mkdirs(f'{install_path}/frpc',True)
|
| 406 |
-
if Path(frpcExePath).exists():
|
| 407 |
-
run(f'cp -f -n {frpcExePath} {install_path}/frpc/frpc')
|
| 408 |
-
else:
|
| 409 |
-
run(f'wget "https://huggingface.co/datasets/ACCA225/Frp/resolve/main/frpc" -O {install_path}/frpc/frpc')
|
| 410 |
-
|
| 411 |
-
for ssl in frpcSSLFFlies:
|
| 412 |
-
if Path(ssl).exists():
|
| 413 |
-
run(f'cp -f -n {ssl}/* {install_path}/frpc/')
|
| 414 |
-
run(f'chmod +x {install_path}/frpc/frpc')
|
| 415 |
-
run(f'{install_path}/frpc/frpc -v')
|
| 416 |
-
if _useNgrok and not is_installed('pyngrok'):
|
| 417 |
-
run('pip install pyngrok')
|
| 418 |
-
|
| 419 |
-
def startProxy():
|
| 420 |
-
if _useNgrok:
|
| 421 |
-
startNgrok(ngrokToken,_server_port)
|
| 422 |
-
if _useFrpc:
|
| 423 |
-
startFrpc('frpc_proxy',frpcStartArg)
|
| 424 |
-
|
| 425 |
-
|
| 426 |
-
# nginx 反向代理配置文件
|
| 427 |
-
def localProxy():
|
| 428 |
-
conf = '''
|
| 429 |
-
server
|
| 430 |
-
{
|
| 431 |
-
listen '''+str(_server_port)+''';
|
| 432 |
-
listen [::]:'''+str(_server_port)+''';
|
| 433 |
-
server_name 127.0.0.1 localhost 0.0.0.0 "";
|
| 434 |
-
|
| 435 |
-
if ($request_method = OPTIONS) {
|
| 436 |
-
return 200;
|
| 437 |
-
}
|
| 438 |
-
fastcgi_send_timeout 10m;
|
| 439 |
-
fastcgi_read_timeout 10m;
|
| 440 |
-
fastcgi_connect_timeout 10m;
|
| 441 |
-
location /1/
|
| 442 |
-
{
|
| 443 |
-
proxy_pass http://127.0.0.1:'''+str(_server_port+2)+'''/;
|
| 444 |
-
# add_header Set-Cookie "subpath=1; expires=0; Path=/";
|
| 445 |
-
# proxy_set_header Set-Cookie "subpath=1; expires=0; Path=/";
|
| 446 |
-
proxy_set_header Host $host;
|
| 447 |
-
proxy_set_header X-Real-IP $remote_addr;
|
| 448 |
-
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
| 449 |
-
proxy_set_header REMOTE-HOST $remote_addr;
|
| 450 |
-
proxy_set_header Upgrade $http_upgrade;
|
| 451 |
-
proxy_set_header Connection upgrade;
|
| 452 |
-
proxy_http_version 1.1;
|
| 453 |
-
proxy_connect_timeout 10m;
|
| 454 |
-
proxy_read_timeout 10m;
|
| 455 |
-
}
|
| 456 |
-
location /
|
| 457 |
-
{
|
| 458 |
-
set $proxy_url http://127.0.0.1:'''+str(_server_port+1)+''';
|
| 459 |
-
# if ($cookie_subpath = "1") {
|
| 460 |
-
# set $proxy_url http://127.0.0.1:'''+str(_server_port+2)+''';
|
| 461 |
-
# }
|
| 462 |
-
proxy_pass $proxy_url;
|
| 463 |
-
proxy_set_header Host $host;
|
| 464 |
-
proxy_set_header X-Real-IP $remote_addr;
|
| 465 |
-
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
| 466 |
-
proxy_set_header REMOTE-HOST $remote_addr;
|
| 467 |
-
proxy_set_header Upgrade $http_upgrade;
|
| 468 |
-
proxy_set_header Connection upgrade;
|
| 469 |
-
proxy_http_version 1.1;
|
| 470 |
-
proxy_connect_timeout 10m;
|
| 471 |
-
proxy_read_timeout 10m;
|
| 472 |
-
}
|
| 473 |
-
}
|
| 474 |
-
'''
|
| 475 |
-
echoToFile(conf,'/etc/nginx/conf.d/proxy_nginx.conf')
|
| 476 |
-
if not check_service('localhost',_server_port):
|
| 477 |
-
run(f'''nginx -c /etc/nginx/nginx.conf''')
|
| 478 |
-
os.system(f'''nginx -s reload''')
|
| 479 |
-
|
| 480 |
-
|
| 481 |
-
import inspect
|
| 482 |
-
import ctypes
|
| 483 |
-
|
| 484 |
-
def _async_raise(tid, exctype):
|
| 485 |
-
"""raises the exception, performs cleanup if needed"""
|
| 486 |
-
tid = ctypes.c_long(tid)
|
| 487 |
-
if not inspect.isclass(exctype):
|
| 488 |
-
exctype = type(exctype)
|
| 489 |
-
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
|
| 490 |
-
if res == 0:
|
| 491 |
-
raise ValueError("invalid thread id")
|
| 492 |
-
elif res != 1:
|
| 493 |
-
# """if it returns a number greater than one, you're in trouble,
|
| 494 |
-
# and you should call it again with exc=NULL to revert the effect"""
|
| 495 |
-
ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
|
| 496 |
-
raise SystemError("PyThreadState_SetAsyncExc failed")
|
| 497 |
-
|
| 498 |
-
def stop_thread(thread):
|
| 499 |
-
_async_raise(thread.ident, SystemExit)
|
| 500 |
-
|
| 501 |
-
def stop_solo_threads():
|
| 502 |
-
# 获取当前所有活动的线程
|
| 503 |
-
threads = threading.enumerate()
|
| 504 |
-
# 关闭之前创建的子线程
|
| 505 |
-
for thread in threads:
|
| 506 |
-
if thread.name.startswith('solo_'):
|
| 507 |
-
print(f'结束线程:{thread.name}')
|
| 508 |
-
try:
|
| 509 |
-
stop_thread(thread)
|
| 510 |
-
except socket.error:
|
| 511 |
-
print(f'结束线程:{thread.name} 执行失败')
|
| 512 |
-
|
| 513 |
-
|
| 514 |
-
envInstalled=False
|
| 515 |
-
quickStart = True
|
| 516 |
-
#安装
|
| 517 |
-
def install():
|
| 518 |
-
print('安装')
|
| 519 |
-
os.chdir(f'''{install_path}''')
|
| 520 |
-
run(f'''git lfs install''')
|
| 521 |
-
run(f'''git config --global credential.helper store''')
|
| 522 |
-
for requirement in requirements:
|
| 523 |
-
run(f'pip install {requirement}')
|
| 524 |
-
if _reLoad:
|
| 525 |
-
run(f'''rm -rf sd_main_dir''')
|
| 526 |
-
if Path("sd_main_dir").exists():
|
| 527 |
-
os.chdir(f'''{install_path}/sd_main_dir/''')
|
| 528 |
-
run(f'''git checkout .''')
|
| 529 |
-
run(f'''git pull''')
|
| 530 |
-
else:
|
| 531 |
-
run(f'''git clone {config.git_proxy}{_sd_git_repo} sd_main_dir''')
|
| 532 |
-
os.chdir(f'''{install_path}/sd_main_dir''')
|
| 533 |
-
print('安装 完成')
|
| 534 |
-
|
| 535 |
-
# 链接输出目录
|
| 536 |
-
def link_dir():
|
| 537 |
-
print('链接输出目录')
|
| 538 |
-
# 链接图片输出目录
|
| 539 |
-
mkdirs(f'{output_path}/outputs',True)
|
| 540 |
-
run(f'''rm -rf {install_path}/sd_main_dir/outputs''')
|
| 541 |
-
run(f'''ln -s -r {output_path}/outputs {install_path}/sd_main_dir/''')
|
| 542 |
-
# 输出收藏目录
|
| 543 |
-
mkdirs(f'{output_path}/log',True)
|
| 544 |
-
run(f'''rm -rf {install_path}/sd_main_dir/log''')
|
| 545 |
-
run(f'''ln -s -r {output_path}/log {install_path}/sd_main_dir/''')
|
| 546 |
-
# 链接训练输出目录 文件夹链接会导致功能不能用
|
| 547 |
-
run(f'''rm -rf {install_path}/sd_main_dir/textual_inversion''')
|
| 548 |
-
mkdirs(f'{output_path}/textual_inversion/',True)
|
| 549 |
-
run(f'''ln -s -r {output_path}/textual_inversion {install_path}/sd_main_dir/''')
|
| 550 |
-
print('链接输出目录 完成')
|
| 551 |
-
|
| 552 |
-
def install_optimizing():
|
| 553 |
-
run('sudo apt install nginx -y')
|
| 554 |
-
run('env TF_CPP_MIN_LOG_LEVEL=1')
|
| 555 |
-
run('sudo apt -y update -qq')
|
| 556 |
-
run('wget http://launchpadlibrarian.net/367274644/libgoogle-perftools-dev_2.5-2.2ubuntu3_amd64.deb')
|
| 557 |
-
run('wget https://launchpad.net/ubuntu/+source/google-perftools/2.5-2.2ubuntu3/+build/14795286/+files/google-perftools_2.5-2.2ubuntu3_all.deb')
|
| 558 |
-
run('wget https://launchpad.net/ubuntu/+source/google-perftools/2.5-2.2ubuntu3/+build/14795286/+files/libtcmalloc-minimal4_2.5-2.2ubuntu3_amd64.deb')
|
| 559 |
-
run('wget https://launchpad.net/ubuntu/+source/google-perftools/2.5-2.2ubuntu3/+build/14795286/+files/libgoogle-perftools4_2.5-2.2ubuntu3_amd64.deb')
|
| 560 |
-
run('sudo apt -y install -qq libunwind8-dev')
|
| 561 |
-
run('dpkg -i *.deb')
|
| 562 |
-
run('env LD_P_reLoad=libtcmalloc.so')
|
| 563 |
-
run('rm *.deb')
|
| 564 |
-
|
| 565 |
-
#安装依赖
|
| 566 |
-
def install_dependencies():
|
| 567 |
-
print('安装需要的python环境')
|
| 568 |
-
global envInstalled
|
| 569 |
-
global venvPath
|
| 570 |
-
run(f'''rm -rf {install_path}/sd_main_dir/venv''')
|
| 571 |
-
mkdirs(f'{install_path}/sd_main_dir/venv',True)
|
| 572 |
-
if str(sys.version).startswith('3.10'):
|
| 573 |
-
try:
|
| 574 |
-
run('python3 -m venv venv' ,cwd=f'{install_path}/sd_main_dir',try_error=False)
|
| 575 |
-
except:
|
| 576 |
-
run('sudo apt install python3.10-venv -y')
|
| 577 |
-
run('python3 -m venv venv' ,cwd=f'{install_path}/sd_main_dir')
|
| 578 |
-
else:
|
| 579 |
-
run('add-apt-repository ppa:deadsnakes/ppa -y')
|
| 580 |
-
run('sudo apt update')
|
| 581 |
-
run('sudo apt install python3.10 -y')
|
| 582 |
-
run('python3.10 -m venv venv',cwd=f'{install_path}/sd_main_dir')
|
| 583 |
-
|
| 584 |
-
if quickStart:
|
| 585 |
-
if not Path(venvPath).exists():
|
| 586 |
-
mkdirs(f'{install_path}/venv_cache',True)
|
| 587 |
-
if not Path(f'{install_path}/venv_cache/venv.tar.bak').exists():
|
| 588 |
-
download_file('https://huggingface.co/viyi/sdwui/resolve/main/venv.zip','venv.zip',f'{install_path}/venv_cache')
|
| 589 |
-
run(f'''unzip {install_path}/venv_cache/venv.zip -d {install_path}/venv_cache''')
|
| 590 |
-
venvPath = f'{install_path}/venv_cache/venv.tar.bak'
|
| 591 |
-
run(f'''rm -rf {install_path}/venv_cache/venv.zip''')
|
| 592 |
-
elif venvPath.endswith('.zip'):
|
| 593 |
-
mkdirs(f'{install_path}/venv_cache',True)
|
| 594 |
-
run(f'''unzip {venvPath} -d {install_path}/venv_cache''')
|
| 595 |
-
venvPath = f'{install_path}/venv_cache/venv.tar.bak'
|
| 596 |
-
print('解压环境')
|
| 597 |
-
run(f'tar -xf {venvPath} -C ./venv',cwd=f'{install_path}/sd_main_dir')
|
| 598 |
-
run(f'rm -rf {install_path}/sd_main_dir/venv.lib')
|
| 599 |
-
if not Path(f'{install_path}/sd_main_dir/venv/bin/pip').exists():
|
| 600 |
-
run('curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py')
|
| 601 |
-
run(f'{install_path}/sd_main_dir/venv/bin/python3 get-pip.py')
|
| 602 |
-
|
| 603 |
-
os.system(f'''{install_path}/sd_main_dir/venv/bin/python3 -V''')
|
| 604 |
-
os.system(f'''{install_path}/sd_main_dir/venv/bin/python3 -m pip -V''')
|
| 605 |
-
|
| 606 |
-
envInstalled = True
|
| 607 |
-
print('安装需要的python环境 完成')
|
| 608 |
-
|
| 609 |
-
# 个性化配置
|
| 610 |
-
def use_config():
|
| 611 |
-
print('使用自定义配置 包括tag翻译 \n')
|
| 612 |
-
mkdirs(f'{install_path}/temp',True)
|
| 613 |
-
run(f'git clone {config.git_proxy}{_sd_config_git_repu} sd-configs',cwd=f'{install_path}/temp')
|
| 614 |
-
run(f'cp -r -f -n {install_path}/temp/sd-configs/dist/* {install_path}/sd_main_dir')
|
| 615 |
-
if not Path(_ui_config_file).exists(): # ui配置文件
|
| 616 |
-
mkdirs(f"{_ui_config_file[:_ui_config_file.rfind('/')]}",True)
|
| 617 |
-
run(f'cp -f -n {install_path}/sd_main_dir/ui-config.json {_ui_config_file}')
|
| 618 |
-
if not Path(_setting_file).exists(): # 设置配置文件
|
| 619 |
-
mkdirs(f"{_setting_file[:_setting_file.rfind('/')]}",True)
|
| 620 |
-
run(f'cp -f -n {install_path}/sd_main_dir/config.json {_setting_file}')
|
| 621 |
-
|
| 622 |
-
def copy_last_log_to_images():
|
| 623 |
-
print('复制编号最大的一张收藏图到输出目录,用于保持编号,否则会出现收藏的图片被覆盖的情况')
|
| 624 |
-
img_list = os.listdir(f'{install_path}/sd_main_dir/log/images')
|
| 625 |
-
last_img_path = ''
|
| 626 |
-
last_img_num = 0
|
| 627 |
-
for img in img_list:
|
| 628 |
-
if re.findall(r'^\d+-',str(img)):
|
| 629 |
-
num = int(re.findall(r'^\d+-',str(img))[0][:-1])
|
| 630 |
-
if num > last_img_num:
|
| 631 |
-
last_img_path = img
|
| 632 |
-
last_img_num = num
|
| 633 |
-
print(f'{install_path}/sd_main_dir/log/images/{last_img_path} {install_path}/sd_main_dir/outputs/txt2img-images')
|
| 634 |
-
mkdirs(f"{install_path}/sd_main_dir/outputs/txt2img-images",True)
|
| 635 |
-
run(f'''cp -f {install_path}/sd_main_dir/log/images/{last_img_path} {install_path}/sd_main_dir/outputs/txt2img-images/''')
|
| 636 |
-
|
| 637 |
-
print(f'{install_path}/sd_main_dir/log/images/{last_img_path} {install_path}/sd_main_dir/outputs/img2img-images')
|
| 638 |
-
mkdirs(f"{install_path}/sd_main_dir/outputs/img2img-images",True)
|
| 639 |
-
run(f'''cp -f {install_path}/sd_main_dir/log/images/{last_img_path} {install_path}/sd_main_dir/outputs/img2img-images/''')
|
| 640 |
-
|
| 641 |
-
def start_webui(i):
|
| 642 |
-
# 只要不爆内存,其他方式关闭后会再次重启 访问地址会发生变化
|
| 643 |
-
print(i,'--port',str(_server_port+1+i))
|
| 644 |
-
if i>0:
|
| 645 |
-
print(f'使用第{i+1}张显卡启动第{i+1}个服务,通过frpc或nrgok地址后加/{i}/进行访问(不能使用同一个浏览器)')
|
| 646 |
-
if _useFrpc:
|
| 647 |
-
restart_times = 0
|
| 648 |
-
last_restart_time = time.time()
|
| 649 |
-
while True:
|
| 650 |
-
os.system(f'''{install_path}/sd_main_dir/venv/bin/python3 launch.py --device-id={i} --port {str(_server_port+1+i)} {'' if i ==0 else '--nowebui'}''')
|
| 651 |
-
print('5秒后重启服务')
|
| 652 |
-
if time.time() - last_restart_time < 30:
|
| 653 |
-
restart_times = restart_times + 1
|
| 654 |
-
else:
|
| 655 |
-
restart_times = 0
|
| 656 |
-
last_restart_time = time.time()
|
| 657 |
-
if restart_times >3 :
|
| 658 |
-
# 如果90秒内重启了3此,将不再自动重启
|
| 659 |
-
break
|
| 660 |
-
time.sleep(5)
|
| 661 |
-
else:
|
| 662 |
-
os.system(f'''{install_path}/sd_main_dir/venv/bin/python3 launch.py --device-id={i} --port {str(_server_port+1+i)} {'' if i ==0 else '--nowebui'}''')
|
| 663 |
-
|
| 664 |
-
# 启动
|
| 665 |
-
def start():
|
| 666 |
-
print('启动')
|
| 667 |
-
os.chdir(f'''{install_path}/sd_main_dir''')
|
| 668 |
-
args = ''
|
| 669 |
-
if _ui_config_file is not None and _ui_config_file != '' and Path(_ui_config_file).exists(): # ui配置文件
|
| 670 |
-
args += ' --ui-config-file=' + _ui_config_file
|
| 671 |
-
if _setting_file is not None and _setting_file != '' and Path(_setting_file).exists(): # 设置配置文件
|
| 672 |
-
args += ' --ui-settings-file=' + _setting_file
|
| 673 |
-
args += ' ' + otherArgs
|
| 674 |
-
os.environ['COMMANDLINE_ARGS']=args
|
| 675 |
-
run(f'''echo COMMANDLINE_ARGS=$COMMANDLINE_ARGS''')
|
| 676 |
-
os.environ['REQS_FILE']='requirements.txt'
|
| 677 |
-
start_webui(0)
|
| 678 |
-
|
| 679 |
-
|
| 680 |
-
# 启动非webui相关的的内容,加快启动速度
|
| 681 |
-
def main():
|
| 682 |
-
global envInstalled
|
| 683 |
-
global huggingface_is_init
|
| 684 |
-
startTicks = time.time()
|
| 685 |
-
stop_solo_threads()
|
| 686 |
-
isInstall = True if os.getenv('IsInstall','False') == 'True' else False
|
| 687 |
-
if Path(f'{install_path}/sd_main_dir').exists():
|
| 688 |
-
isInstall = True
|
| 689 |
-
if isInstall is False or _reLoad:
|
| 690 |
-
print('启动 安装和运行环境')
|
| 691 |
-
install()
|
| 692 |
-
link_dir()
|
| 693 |
-
threading.Thread(target = install_dependencies,daemon=True,name='solo_install_dependencies').start()
|
| 694 |
-
threading.Thread(target = install_optimizing,daemon=True,name='solo_install_optimizing').start()
|
| 695 |
-
threading.Thread(target = installProxyExe,daemon=True).start()
|
| 696 |
-
link_or_download_flie(replace_path(_async_downloading), _link_instead_of_copy=_link_instead_of_copy,
|
| 697 |
-
base_path=f'{install_path}/sd_main_dir')
|
| 698 |
-
|
| 699 |
-
link_or_download_flie(replace_path(_before_downloading), _link_instead_of_copy=_link_instead_of_copy,
|
| 700 |
-
base_path=f'{install_path}/sd_main_dir',is_await=True)
|
| 701 |
-
t = 0
|
| 702 |
-
while not envInstalled:
|
| 703 |
-
if t%10==0:
|
| 704 |
-
print('等待python环境安装...')
|
| 705 |
-
t = t+1
|
| 706 |
-
time.sleep(1)
|
| 707 |
-
use_config()
|
| 708 |
-
localProxy()
|
| 709 |
-
os.environ['IsInstall'] = 'True'
|
| 710 |
-
else:
|
| 711 |
-
envInstalled = True
|
| 712 |
-
link_or_download_flie(replace_path(_before_start_sync_downloading), _link_instead_of_copy=_link_instead_of_copy,
|
| 713 |
-
base_path=f'{install_path}/sd_main_dir',sync=True)
|
| 714 |
-
threading.Thread(target = startProxy, daemon=True, name='solo_startProxy').start()
|
| 715 |
-
ticks = time.time()
|
| 716 |
-
print("安装耗时:",(ticks - startTicks),"秒")
|
| 717 |
-
start()
|
| 718 |
-
|
| 719 |
-
|
| 720 |
-
if _skip_start:
|
| 721 |
-
print('已跳过自动启动,可手动执行 main() 进行启动。')
|
| 722 |
-
print('''推荐的启动代码:
|
| 723 |
-
try:
|
| 724 |
-
check_gpu() # 检查是否存在gpu
|
| 725 |
-
main()
|
| 726 |
-
except KeyboardInterrupt:
|
| 727 |
-
stop_solo_threads() # 中断后自动停止后台线程 (有部分功能在后台线程中运行)
|
| 728 |
-
''')
|
| 729 |
-
else:
|
| 730 |
-
try:
|
| 731 |
-
main()
|
| 732 |
-
except KeyboardInterrupt:
|
| 733 |
-
stop_solo_threads()
|
| 734 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
stable-diffusion-webui-novelai-sdxl.ipynb
DELETED
|
@@ -1 +0,0 @@
|
|
| 1 |
-
{"cells":[{"cell_type":"markdown","metadata":{},"source":["# NovelAi stable-diffusion-webui+api+sdxl\n","---\n","**version: 1.6.0 • python: 3.10.6 • torch: 2.0.1+cu118 • xformers: 0.0.21 • gradio: 3.41.2**\n","- 发布地址 [kaggle stable-diffusion-webui-novelai](https://www.kaggle.com/code/yiyiooo/stable-diffusion-webui-novelai)\n","- 这是一个用于快速体验ai绘画项目 [stable-diffusion-webui](https://github.com/AUTOMATIC1111/stable-diffusion-webui) 的笔记本,你可以直接启动就能在线体验ai绘图的乐趣。 \n","- kaggle和colab都是AI学习平台,请勿浪费计算资源,如果有需求,可以考虑AutoDL这类租用显卡的平台或者colab付费使用。\n","- 在保持可以免配置直接启动的情况下也提供了很多可自定义的配置,在下方的配置项里,请自行查看。 \n","- 同时也为新人提供了一份基础的帮助文档,包含了一些使用中可能遇到的问题,如果使用过程中有什么疑问,不妨先看看帮助文档。\n","- 如果你需要在此脚本上修改再发布,请随意,但请遵守相关法律法规,文明使用。\n","- 使用时如果遇到问题,尽可能通过帮助文档或者参考已有内容尝试自己解决。\n","- Q群 [816545732](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=OGQydingTPku9M_myV_cscWv6MVaCSde&authKey=RFadQ18FgReFkx7CRs8SNk4vHpxHz%2FD2ojHL3433MehuQOBlnG0hhWFIo8AX%2BFRU&noverify=0&group_code=816545732) ,这是我建的新群,如果有需要,可以进群,其实这个笔记已经非常简洁了,进群大概也不会有啥帮助。\n","- 使用前可以看一下最后的更新日志,可能有功能更新需要注意"]},{"cell_type":"markdown","metadata":{},"source":["## 重要文件列表\n","\n","- **这个列表仅加载一次 且会等待加载完成再开始安装sd**\n","- ```[]```内的是下载文件的目标目录,可以是相对目录也可以是觉得路径\n","- ```[]```的下一行就是文件列表,可以是下载地址、git仓库、文件路径、文件夹路径,且支持通配符\n","- 如果需要对下载的文件重命名,可以在下载链接前面写上文件名后加一个```:```分开文件名和下载地址\n","- 如果需要下载到其他目录,可以使用同样的格式写其他目录"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["before_downloading = '''# 这个列表仅加载一次 且会等待加载完成再开始安装sd\n","[extensions] # 插件 如果你需要增加插件,把插件地址写到这来就行,支持git仓库和文件夹路径\n","https://github.com/dtlnor/stable-diffusion-webui-localization-zh_CN.git\n","https://github.com/AlUlkesh/stable-diffusion-webui-images-browser.git\n","https://github.com/DominikDoom/a1111-sd-webui-tagcomplete.git\n","https://github.com/Mikubill/sd-webui-controlnet.git\n","https://github.com/ilian6806/stable-diffusion-webui-state.git\n","https://github.com/pkuliyi2015/multidiffusion-upscaler-for-automatic1111.git\n","https://github.com/Bing-su/adetailer.git\n","https://github.com/zanllp/sd-webui-infinite-image-browsing.git\n","https://github.com/viyiviyi/stable-diffusion-webui-zoomimage.git\n","https://github.com/viyiviyi/sd-encrypt-image.git # 图片加密插件,解决涩图封号问题,需要在参数里设置你的密码开启\n","\n","# 如果你有模型文件需要在启动前加载,可以写在这个下面对应位置\n","\n","[models/Stable-diffusion] # 大模型列表\n","\n","[models/hypernetworks] # hypernetworks文件列表\n","\n","[models/embeddings] # embeddings文件列表\n","\n","[models/Lora] # Lora文件列表\n","\n","[models/VAE] # VAE文件列表\n","\n","[extensions/sd-webui-controlnet/models] # controlnet插件的模型列表\n","\n","'''"]},{"cell_type":"markdown","metadata":{},"source":["## 普通文件列表\n","\n","- **这个列表仅加载一次 且不会等待加载完成**\n","- ```[]```内的是下载文件的目标目录,可以是相对目录也可以是觉得路径\n","- ```[]```的下一行就是文件列表,可以是下载地址、git仓库、文件路径、文件夹路径,且支持通配符\n","- 如果需要对下载的文件重命名,可以在下载链接前面写上文件名后加一个```:```分开文件名和下载地址\n","- 如果需要下载到其他目录,可以使用同样的格式写其他目录"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["async_downloading='''# 这个列表仅加载一次 且不会等待加载完成\n","[extensions] # 插件 如果你没有使用ngrok或者frpc,请不要把插件放在这里加载,因为这里的文件可能在webui启动后才加载完成\n","\n","[models/Stable-diffusion] # 大模型列表\n","https://huggingface.co/viyi/testing_models/resolve/main/mg-LBG.safetensors\n","容华_国风_SDXL.safetensors:https://civitai.com/api/download/models/151978\n","\n","[models/hypernetworks] # hypernetworks文件列表\n","\n","[models/embeddings] # embeddings文件列表\n","\n","[models/Lora] # Lora文件列表\n","Genshin_Impact_all-in-one.safetensors:https://civitai.com/api/download/models/116970\n","https://civitai.com/api/download/models/117151 # Clothing +/- Adjuster 衣物增/减 LoRA\n","https://civitai.com/api/download/models/62833 # Detail Tweaker LoRA (细节调整LoRA)\n","\n","[models/VAE] # VAE文件列表\n","{input_path}/vae-ft-ema-prunedsafetensors/vae-ft-ema-560000-ema-pruned.safetensors\n","{input_path}/vae-ft-ema-prunedsafetensors/vae-ft-mse-840000-ema-pruned.safetensors\n","https://huggingface.co/stabilityai/sd-vae-ft-ema-original/resolve/main/vae-ft-ema-560000-ema-pruned.safetensors\n","https://huggingface.co/WarriorMama777/OrangeMixs/resolve/main/VAEs/orangemix.vae.pt\n","sdxl_vae.safetensors:https://civitai.com/api/download/models/130720?type=VAE # sdxl模型需要sdxl的vae\n","\n","[extensions/sd-webui-controlnet/models] # controlnet插件的模型列表\n","https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11e_sd15_ip2p_fp16.safetensors\n","https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11e_sd15_shuffle_fp16.safetensors\n","https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11f1e_sd15_tile_fp16.safetensors\n","https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11f1p_sd15_depth_fp16.safetensors\n","https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_canny_fp16.safetensors\n","https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_inpaint_fp16.safetensors\n","https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_lineart_fp16.safetensors\n","https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_mlsd_fp16.safetensors\n","https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_normalbae_fp16.safetensors\n","https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_openpose_fp16.safetensors\n","https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_scribble_fp16.safetensors\n","https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_seg_fp16.safetensors\n","https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_softedge_fp16.safetensors\n","https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15s2_lineart_anime_fp16.safetensors\n","https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11u_sd15_tile_fp16.safetensors\n","'''\n"]},{"cell_type":"markdown","metadata":{},"source":["## 按顺序加载的重要文件列表\n","\n","- **这个列表每次 run all 启动都会加载一次,且一定按照顺序加载后才启动webui**\n","- ```[]```内的是下载文件的目标目录,可以是相对目录也可以是觉得路径\n","- ```[]```的下一行就是文件列表,可以是下载地址、git仓库、文件路径、文件夹路径,且支持通配符\n","- 如果需要对下载的文件重命名,可以在下载链接前面写上文件名后加一个```:```分开文件名和下载地址\n","- 如果需要下载到其他目录,可以使用同样的格式写其他目录"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["before_start_sync_downloading = ''' # 这个列表每次 run all 启动都会加载一次,且一定按照顺序加载\n","\n","# 如果你需要每次启动都加载一下文件,可以写在这。(比如测试路径是否正确的时候)\n","\n","[models/Stable-diffusion] # 大模型列表\n","\n","[models/hypernetworks] # hypernetworks文件列表\n","\n","[models/embeddings] # embeddings文件列表\n","\n","[models/Lora] # Lora文件列表\n","\n","[models/VAE] # VAE文件列表\n","\n","[extensions/sd-webui-controlnet/models] # controlnet插件的模型列表\n","\n","'''"]},{"cell_type":"markdown","metadata":{},"source":["## webui 启动参数\n","- 所有的参数都会在启动时传入\n","- 可以在前面加```#```来屏蔽某个参数\n","- 端口参数需要在下一个代码块的```webuiPort```处修改"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["sd_start_args='''\n","# --ckpt=mg-Tender.safetensors # 默认模型名称,路径不能包含空格\n","--disable-safe-unpickle \n","--deepdanbooru \n","--no-hashing \n","--no-download-sd-model \n","--administrator\n","--skip-torch-cuda-test \n","--skip-version-check \n","--disable-nan-check\n","# --opt-sdp-attention \n","--opt-sdp-no-mem-attention \n","--xformers-flash-attention\n","--xformers\n","--api \n","--listen\n","--lowram\n","#--no-gradio-queue\n","#--encrypt-pass=123qwe # 图片加密插件的密码,如果要启用图片加密插件,删除这一行前面的#和将123qwe改成你的密码,也可以不改\n","# --share # 默认的内网穿透在kaggle和colab都已经不可用,请考虑其他方案\n","--disable-console-progressbars\n","--no-half-vae \n","# --no-half #关闭半精度\n","# --enable-console-prompts\n","# --nowebui # 如果只需要api服务,可以开启这个\n","# --api-auth=2333:6666 # api密码\n","# --gradio-auth=2333:6666 # webui密码\n","'''"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["useGooglrDrive = True # 连接到谷歌云盘 在google colab环境才会生效\n","#Ngrok\n","useNgrok=True # 非必填 是否使用ngrok作为公网访问地址\n","#Frpc\n","useFrpc=True # 开启frp将不能启动\n","\n","#可以填写文件路径 或 直接填 token 内容\n","ngrok_config_or_file = '''\n","{input_path}/configs/ngrok_token.txt\n","'''\n","frp_config_or_file = '''\n","{input_path}/configs/frpc_litechat.ini\n","'''\n","frp_ssl_dir = '''\n","{input_path}/configs/litechat_nginx\n","'''\n","\n","# 配置启动参数\n","server_port=7860 # webui 默认端口\n","\n","# 仓库地址 这是修改过界面布局顺序的webui,不定期同步到官方版本\n","# 如果要使用官方版本,改成这个: https://github.com/AUTOMATIC1111/stable-diffusion-webui\n","sd_git_repo='https://github.com/viyiviyi/stable-diffusion-webui.git -b local' \n","# 配置文件,包括webui的设置和UI默认值,如果要自定义,fork这个仓库后修改并把地址替换这个地址\n","sd_config_git_repu = 'https://github.com/viyiviyi/sd-configs.git'\n","# 设置文件保存路径 当使用谷歌云盘时非常有用\n","setting_file = '{output_path}/configs/config.json'\n","ui_config_file = '{output_path}/configs/ui-config.json'\n","\n","# 这是配置文件夹同步的相关配置\n","# 需要在huggingface创建一个数据集(datasets) 然后把数据集的名称(在页面上有复制的按钮)填到 huggingface_repo \n","# 需要获取 token 填到 huggingface_token 获取的地址是: https://huggingface.co/settings/tokens\n","huggingface_token = '{input_path}/configs/huggingface_token_file.txt'\n","huggingface_repo = 'viyi/sdwui-imgs'\n"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["link_instead_of_copy = True # 下载或加载Input的文件时是使用链接还是复制的方式加载到目标目录\n","hidden_console_info = True # 是否隐藏大部分的控制台内容"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["# 保存当前目录和启动时cd到之前保存的目录,可以减少sdwui-start-new.ipynb文件下载次数\n","import os\n","INIT_WORK_PATH = os.environ['HOME']\n","if os.getenv('INIT_WORK_PATH',''):\n"," INIT_WORK_PATH = os.getenv('INIT_WORK_PATH','')\n","else:\n"," os.environ['INIT_WORK_PATH'] = os.getcwd()\n","%cd {INIT_WORK_PATH}"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["reLoad = True\n","# 如果需要重新安装,请注释下面这一行\n","reLoad = False"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["if not os.path.exists('sdwui-start-util.ipynb'):\n"," !wget https://huggingface.co/viyi/sdwui/resolve/main/sdwui-start-util.ipynb -o log.log\n","%run sdwui-start-util.ipynb"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["try:\n"," check_gpu() # 检查是否存在gpu\n"," main()\n","except KeyboardInterrupt:\n"," stop_solo_threads() # 中断后自动停止后台线程 (有部分功能在后台线程中运行)"]},{"cell_type":"code","execution_count":null,"metadata":{"trusted":true},"outputs":[],"source":["# 打包收藏文件夹 如果需要可以取消下面两行的注释\n","# zipPath('$install_path/sd_main_dir/log','log')\n","# !mv {output_path}/log.tar {output_path}/log.tar.bak\n","# createOrUpdateDataSet(f'{output_path}/log.tar.bak','sd-webui-log-bak')\n","\n","# 打包 这一行的结果是 压缩一个目录,并放在 output_path: /kaggle/working/ 目录下 名字是训练输出.tar\n","# zipPath('$install_path/sd_main_dir/textual_inversion','训练输出') \n","# zipPath('$install_path/sd_main_dir/outputs','outputs')\n","\n","# 打包venv并上传到数据集\n","# zipPath('$install_path/sd_main_dir/venv','venv')\n","# !mv {output_path}/venv.tar /kaggle/working/venv.tar.bak\n","# createOrUpdateDataSet('/kaggle/working/venv.tar.bak','sd-webui-venv')\n","\n","# 打包命令参考,--exclude 可以排除不需要打包的目录\n","# !tar -cf $output_path/webui.tar.bak --exclude=venv --exclude=extensions -C /sd_main_dir/ ."]},{"cell_type":"markdown","metadata":{},"source":["# 使用帮助\n","---\n","**代码块不能删除也不能调换顺序,如果出现变量未定义,请检查是否按顺序执行了代码块**\n","\n","---\n","\n","## kaggle账号\n","- 注册账号需要手机号,国内手机号也行,如果点击注册后没反应,估计是需要梯子,用于人机验证\n","- 注册后点此笔记的 **Copy & Edit** 按钮就进到编辑界面\n","\n","## 准备工作\n","1. 右侧面板 **Notebook options/ACCELERATOR** 需要选择GPU **T4x2**出图更快\n","2. 右侧面板 **Notebook options/LANGUAGE** 需要选择Python\n","2. 右侧面板 **Notebook options/PERSISTENCE** 建议选择 Files only **作用是保存Outpot目录内的文件,当前这个功能并没有任何作用**\n","3. 右侧面板 **Notebook options/ENVIRONMENT** 建议不改这个配置,使用当前默认值就行\n","4. 右侧面板 **Notebook options/INTERNET** 需要打开 用于联网\n","\n","## 启动\n","#### 启动方式一 **直接点击页面上边的 RunAll**\n","- 手机端可能会出现页面上边的工具栏不显示的情况,左侧菜单按钮里也有相关的操作\n","- 长时间不操作页面会导致脚本停止 (应该是40分钟吧)\n","\n","#### 启动方式二 **使用页面上边的 Save Version 后台运行**\n","- 后台运行不用担心长时间不操作脚本停止\n","- Version Type 选择 **Save & Run All**\n","- 在Save Version弹窗里需要选择使用**GPU**环境 (Advanced Settings 里最后一个选项)\n","\n","## 访问\n","- 如果你使用了ngrok或者frpc,可以访问你这两对应的地址\n","- 如果你不知道你的ngrok或者frpc的地址可以在控制台(页面最下方Console)的输出里面查看\n","- 使用Run All方式启动,控制台在启动完成后会输出访问网址,网址内容包含**gradio.live**,可以在页面中搜索快速找到\n","- 如果使用Save Verson的方式启动,点击左下角的**View Active Events**点击刚刚启动的脚步,在**Log**里找访问网址\n","- 一般情况下第一次启动此脚本需要等待kaggle下载模型文件,进度在页面上方\n","- 第二次及以后(不增加新的文件)需要3到5分钟\n","\n","## 增加模型\n","- 可以直接写模型的下载链接,省去下面这些步骤\n","1. 先创建数据集,也就是dataset\n","2. 创建时需要添加文件,选择自己的模型文件就行\n","3. 同类型文件放相同的数据集里面,一个数据集也不要太大\n","4. 可以在dataset搜索其他人上传的模型\n","5. 通过右侧的 **Add Data** 按钮选择已经上传的模型文件或者别人上传的模型文件\n"," - input 下面的列表就是模型文件,可以点击名称后面的复制按钮复制路径\n","6. 将模型路径放在配置里的对应配置里即可,支持文件夹和文件路径,参考 **modelDirs**\n"," - 如果目录里还有子目录也是需要加载的,可以用*表示子目录 例子:比如Loras目录下还有角色、画风、涩涩的文件夹,那路径里写成 '/kaggle/input/Loras/*'就可以加载子目录里面的文件了\n"," - 模型加载使用的文件链接方式,如果你融模型的时候新模型名字和原有模型名字一样,会出现不能修改只读文件的错误\n"," - 同理,直接对模型做编辑的工具可能也会出现相同的错误\n"," \n"," \n","- **受到kaggle内存大小的影响,切换多个模型后大概率爆内存导致停止运行**\n"," \n","**下边的配置项都写了对应配置的作用和使用说明,不理解的话也不用改,用默认的就好**\n","\n","## 下载文件\n","#### 方式一\n","- 在浏览器直接下 比如你需要下载的文件路径在 /kaggle/stable-diffusion-webui/models/Lora/dow_a.safetensors\n"," - 比如你需要下载的文件路径在 /kaggle/stable-diffusion-webui/models/Lora/dow_a.safetensors\n"," - 你的访问地址是 https://123123123.gradio.live\n"," - 则可以在浏览器输入 https://123123123.gradio.live/file=/kaggle/stable-diffusion-webui/models/Lora/dow_a.safetensors 下载你的文件\n"," \n","#### 方式二\n","- 复制到Output目录下载 仅支持使用Run All方式运行的\n"," - 比如你需要下载的文件路径在 /kaggle/stable-diffusion-webui/models/Lora/dow_a.safetensors\n"," - 先停止笔记本(不是关机,是停止)\n"," - 然后新建一个代码块,在里面输入 !cp -f /kaggle/stable-diffusion-webui/models/Lora/dow_a.safetensors /kaggle/working/\n"," - 或者 新建一个代码块,在里面输入 !cp -f \\$install_path/stable-diffusion-webui/models/Lora/dow_a.safetensors /kaggle/working/\n"," - 你可能需要拼接路径 如果是在webui里面看到的路径,且路径里面没有带**stable-diffusion-webui**\n"," - 拼接方式是 **\\$install_path/stable-diffusion-webui** + **文件路径** 拼成类似前一条的样子\n"," - 就可以在右侧列表的Output目录看见复制出来的文件,点击下载即可\n","\n","## **一些可能没用的说明**\n","- 配置说明 **True或者False**表示布尔值 **True**表示“**是**” **False**表示“**否**” 只有这两个值\n","- 配置说明 **[]** 表示数组,里面可以存放内容,每个内容需要用**英语(半角)逗号**隔开\n","- 配置说明 **''或者\"\"** 英语(半角)的双引号或者单引号包裹的内容是**字符串**,比如放在数组里面的路径就需要是一个字符串\n","- 配置说明 **#** **#** 后面的内容是**注释**,是帮助性内容,对整个代码的执行不会有影响\n"]},{"cell_type":"markdown","metadata":{},"source":["# 更新记录\n","#### 231011 v180\n","- 增加了图片加密插件,默认不启用,请查看启动参数部分设置密码启动,批量解密图片可以查看插件的发布地址\n","\n","#### 230920 v177\n","- 默认不再开启gradio这个内网穿透\n","- 更新了一些文档和说明\n","\n","#### 230910 v175\n","- 增加了默认的sdxl模型\n","- 修改了不合适的使用说明\n","\n","#### 230901 v173\n","- 更新了依赖版本,可以加载sdxl模型了\n","- 增加代码块内容说明,希望有用\n","\n","#### 230812 v171\n","- 把关闭半精度的参数注释了,这是之前写错的,注释后不容易爆内存\n","- 增加默认模型的参数,用于指定模型启动时默认的模型\n","\n","#### 230726 v170\n","- 更新了整个配置,可以更加自由的下载和加载文件\n","- 删除了大部分参数\n","\n","#### 230726 v169\n","- 增加了一个文件加载配置,可以自定义把文件或下载地址加载到指定目录,配置方式见 [ 其他文件列表 ]\n","- 增加了一个配置,可以隐藏部分控制台输出,但隐藏不完全,没啥用\n","\n","#### 230719 v168\n","- 增加了同步收藏文件夹到 huggingface 数据集的功能,仅同步收藏文件夹,如果同步所有图片也太浪费资源了\n","\n","#### 230716 v167\n","- 账号解封了\n","- 已经更新为精简自动更新版,主要逻辑分离存放到 [huggingface](https://huggingface.co/viyi/sdwui),这边基本上不再需要更新\n","- 如果增加了新功能需要新的配置,可以在输出内容的最前面查看到(暂定)\n","\n","#### 230302 v165\n","- 可以修改disableShared=True来使用pm2启动,做到爆内存自动重启(需要使用frpc或者ngrok代理,否则无法访问界面)\n","\n","#### 230228 v156\n","- 移除了koishi的相关功能 如需使用,可查看 [sd-webui-koishi](https://www.kaggle.com/code/yiyiooo/sd-webui-koishi)\n","\n","#### 230227 v147\n","- 增加了nginx做反向代理,现在可以使用一个ngrok地址访问多个服务了 功能在版本156移除\n","\n","#### 230225 v139\n","- 可以加载ssl证书,启动https的隧道了\n","\n","#### 230224 v134\n","- 可以自动修改frp的本地端口\n","\n","#### 230224 v128\n","- 修复默认模型文件不存在时不能启动的问题\n","- 修复了多线程导致依赖等内容安装位置错乱的问题\n","- 修复了第一次启动会更新koishi数据对应的数据集问题\n","- 增加了配置检查功能,对一些配置项做了提示\n","- 增加了可配置webui端口功能,现在可以配置webui、froc、ngrok的端口了\n","\n","#### 230223 v126\n","- 修复了仅适用koishi数据目录无法启动koishi的问题\n","- 修改了部分文档\n","\n","#### 230223 v124\n","- 修复使用多线程后出现的文件安装下载目录失败的问题\n","- 修复使用多线程后文件目录错乱问题\n","\n","#### 230222 v123\n","- 使用多线程进行安装,节省安装时间\n","\n","#### 230222 v122\n","- 更改了默认配置,现在训练的输出可以在Output下面查看了\n","\n","#### 230222 v118\n","- 增加了自动上传koishi的数据到数据集且能自动下载的功能\n"," - 自动上传的数据集优先级高于手动上传的\n"," - 上一个版本的数据集与当前版本的目录结构有差异,如果更新后需要修改配置\n"," \n","#### 230121 v111\n","- 增加了koishi的部署相关功能 功能在版本156移除\n","\n","#### 230220 v110\n","- 增加了ControlNet插件的一些说明\n","\n","#### 230220 v109\n","- 修复第二次Run all时不能切换到新的frpc配置问题\n","- 增加更新记录,用于记录每次更新 "]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.6.4"}},"nbformat":4,"nbformat_minor":4}
|
|
|
|
|
|
stable-diffusion-webui-novelai.ipynb
DELETED
|
@@ -1 +0,0 @@
|
|
| 1 |
-
{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# NovelAi stable-diffusion-webui+api+sdxl\n---\n**version: 1.6.0 • python: 3.10.6 • torch: 2.0.1+cu118 • xformers: 0.0.21 • gradio: 3.41.2**\n- 发布地址 [kaggle stable-diffusion-webui-novelai](https://www.kaggle.com/code/yiyiooo/stable-diffusion-webui-novelai)\n- 这是一个用于快速体验ai绘画项目 [stable-diffusion-webui](https://github.com/AUTOMATIC1111/stable-diffusion-webui) 的笔记本,你可以直接启动就能在线体验ai绘图的乐趣。 \n- 在保持可以免配置直接启动的情况下也提供了很多可自定义的配置,在下方的配置项里,请自行查看。 \n- 同时也为新人提供了一份基础的帮助文档,包含了一些使用中可能遇到的问题,如果使用过程中有什么疑问,不妨先看看帮助文档。\n- 如果你需要在此脚本上修改再发布,请随意,但请遵守相关法律法规,文明使用。\n- 交流群632428790 这是 [qq2575044704](https://www.kaggle.com/qq2575044704) 的群,感谢他为这个笔记做了一些宣传。\n","metadata":{}},{"cell_type":"markdown","source":"## 重要文件列表\n\n- **这个列表仅加载一次 且会等待加载完成**\n- ```[]```内的是下载文件的目标目录,可以是相对目录也可以是觉得路径\n- ```[]```的下一行就是文件列表,可以是下载地址、git仓库、文件路径、文件夹路径,且支持通配符\n- 如果需要对下载的文件重命名,可以在下载链接前面写上文件名后加一个```:```分开文件名和下载地址\n- 如果需要下载到其他目录,可以使用同样的格式写其他目录","metadata":{}},{"cell_type":"code","source":"重要文件列表 = '''# 这个列表仅加载一次 且会等待加载完成\n[extensions] # 插件\nhttps://github.com/dtlnor/stable-diffusion-webui-localization-zh_CN.git\nhttps://github.com/AlUlkesh/stable-diffusion-webui-images-browser.git\nhttps://github.com/DominikDoom/a1111-sd-webui-tagcomplete.git\nhttps://github.com/Mikubill/sd-webui-controlnet.git\nhttps://github.com/KohakuBlueleaf/a1111-sd-webui-lycoris.git\nhttps://github.com/LianZiZhou/sd-webui-pixink-console.git\nhttps://github.com/ilian6806/stable-diffusion-webui-state.git\nhttps://github.com/pkuliyi2015/multidiffusion-upscaler-for-automatic1111.git\nhttps://github.com/Bing-su/adetailer.git\nhttps://github.com/civitai/sd_civitai_extension.git\nhttps://github.com/zanllp/sd-webui-infinite-image-browsing.git\nhttps://github.com/viyiviyi/stable-diffusion-webui-zoomimage.git\n\n# 如果你有模型文件需要在启动前加载,可以写在这个下面对应位置\n\n[models/Stable-diffusion] # 大模型列表\n\n[models/hypernetworks] # hypernetworks文件列表\n\n[models/embeddings] # embeddings文件列表\n\n[models/Lora] # Lora文件列表\n\n[models/LyCORIS] # LyCORIS文件列表\n\n[models/VAE] # VAE文件列表\n\n[extensions/sd-webui-controlnet/models] # controlnet插件的模型列表\n\n'''","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 普通文件列表\n\n- **这个列表仅加载一次 且不会等待加载完成**\n- ```[]```内的是下载文件的目标目录,可以是相对目录也可以是觉得路径\n- ```[]```的下一行就是文件列表,可以是下载地址、git仓库、文件路径、文件夹路径,且支持通配符\n- 如果需要对下载的文件重命名,可以在下载链接前面写上文件名后加一个```:```分开文件名和下载地址\n- 如果需要下载到其他目录,可以使用同样的格式写其他目录","metadata":{}},{"cell_type":"code","source":"普通文件列表='''# 这个列表仅加载一次 且不会等待加载完成\n[extensions] # 插件 如果你没有使用ngrok或者frpc,请不要把插件放在这里加载,因为这里的文件可能在webui启动后才加载完成\n\n[models/Stable-diffusion] # 大模型列表\nmg-Tender.safetensors:https://civitai.com/api/download/models/75587\n\n[models/hypernetworks] # hypernetworks文件列表\n\n[models/embeddings] # embeddings文件列表\n\n[models/Lora] # Lora文件列表\nGenshin_Impact_all-in-one.safetensors:https://civitai.com/api/download/models/116970\n\n[models/LyCORIS] # LyCORIS文件列表\n\n\n[models/VAE] # VAE文件列表\n{input_path}/vae-ft-ema-prunedsafetensors/vae-ft-ema-560000-ema-pruned.safetensors\n{input_path}/vae-ft-ema-prunedsafetensors/vae-ft-mse-840000-ema-pruned.safetensors\nhttps://huggingface.co/WarriorMama777/OrangeMixs/resolve/main/VAEs/orangemix.vae.pt\n\n[extensions/sd-webui-controlnet/models] # controlnet插件的模型列表\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11e_sd15_ip2p_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11e_sd15_shuffle_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11f1e_sd15_tile_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11f1p_sd15_depth_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_canny_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_inpaint_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_lineart_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_mlsd_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_normalbae_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_openpose_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_scribble_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_seg_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_softedge_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15s2_lineart_anime_fp16.safetensors\nhttps://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11u_sd15_tile_fp16.safetensors\n'''\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 按顺序加载的重要文件列表\n\n- **这个列表每次 run all 启动都会加载一次,且一定按照顺序加载后才启动webui**\n- ```[]```内的是下载文件的目标目录,可以是相对目录也可以是觉得路径\n- ```[]```的下一行就是文件列表,可以是下载地址、git仓库、文件路径、文件夹路径,且支持通配符\n- 如果需要对下载的文件重命名,可以在下载链接前面写上文件名后加一个```:```分开文件名和下载地址\n- 如果需要下载到其他目录,可以使用同样的格式写其他目录","metadata":{}},{"cell_type":"code","source":"按顺序加载的重要文件列表 = ''' # 这个列表每次 run all 启动都会加载一次,且一定按照顺序加载\n\n# 如果你需要每次启动都加载一下文件,可以写在这。(比如测试路径是否正确的时候)\n\n[models/Stable-diffusion] # 大模型列表\n\n[models/hypernetworks] # hypernetworks文件列表\n\n[models/embeddings] # embeddings文件列表\n\n[models/Lora] # Lora文件列表\n\n[models/LyCORIS] # LyCORIS文件列表\n\n[models/VAE] # VAE文件列表\n\n[extensions/sd-webui-controlnet/models] # controlnet插件的模型列表\n\n'''","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## webui 启动参数\n- 所有的参数都会在启动时传入\n- 可以在前面加```#```来屏蔽某个参数\n- 端口参数需要在下一个代码块的```webuiPort```处修改","metadata":{}},{"cell_type":"code","source":"参数列表='''\n--ckpt=mg-Tender.safetensors # 默认模型名称,路径不能包含空格\n--disable-safe-unpickle \n--deepdanbooru \n--no-hashing \n--no-download-sd-model \n--administrator\n--skip-torch-cuda-test \n--skip-version-check \n--disable-nan-check\n# --opt-sdp-attention \n--opt-sdp-no-mem-attention \n--xformers-flash-attention\n--xformers\n--api \n--listen\n--lowram\n--no-gradio-queue\n--share\n--disable-console-progressbars\n--no-half-vae \n# --no-half #关闭半精度\n# --enable-console-prompts\n# --nowebui\n# --api-auth=2333:6666 # api密码\n# --gradio-auth=2333:6666 # webui密码\n'''","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"useGooglrDrive = True # 连接到谷歌云盘 在google colab环境才会生效\n#Ngrok\nuseNgrok=True # 非必填 是否使用ngrok作为公网访问地址\n#Frpc\nuseFrpc=True # 开启frp将不能启动\n\n#文件或直接填配置\nngrok配置或文件地址='''\n{input_path}/configs/ngrok_token.txt\n'''\nfrp配置文件或配置='''\n{input_path}/configs/frpc_litechat.ini\n'''\nfrpSSL文件='''\n{input_path}/configs/litechat_nginx\n'''\n\n# 配置启动参数\nwebuiPort=7860 # webui默认端口\n\n# 仓库地址 这是修改过界面布局顺序的webui,不定期同步到官方版本\n# 如果要使用官方版本,改成这个: https://github.com/AUTOMATIC1111/stable-diffusion-webui\nwebui_git_repo='https://github.com/viyiviyi/stable-diffusion-webui.git -b local' \n# 配置文件,包括webui的设置和UI默认值,如果要自定义,fork这个仓库后修改并把地址替换这个地址\nwebui_config_git_repu = 'https://github.com/viyiviyi/sd-configs.git'\n# 设置文件保存路径 当使用谷歌云盘时非常有用\nsetting_file = '{output_path}/configs/config.json'\nui_config_file = '{output_path}/configs/ui-config.json'\n\n# 这是配置文件夹同步的相关配置\n# 需要在huggingface创建一个数据集(datasets) 然后把数据集的名称(在页面上有复制的按钮)填到 huggingface_repo \n# 需要获取 token 填到 huggingface_token 获取的地址是: https://huggingface.co/settings/tokens\nhuggingface_token = '{input_path}/configs/huggingface_token.txt'\nhuggingface_repo = 'viyi/sdwui-log'\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"link_instead_of_copy = True # 下载或加载Input的文件时是使用链接还是复制的方式加载到目标目录\nhidden_console_info = True # 是否隐藏大部分的控制台内容","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 保存当前目录和启动时cd到之前保存的目录,可以减少sdwui-start-new.ipynb文件下载次数\nimport os\nINIT_WORK_PATH = os.environ['HOME']\nif os.getenv('INIT_WORK_PATH',''):\n INIT_WORK_PATH = os.getenv('INIT_WORK_PATH','')\nelse:\n os.environ['INIT_WORK_PATH'] = os.getcwd()\n%cd {INIT_WORK_PATH}","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"reLoad = True\n# 如果需要重新安装,请注释下面这一行\nreLoad = False","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not os.path.exists('sdwui-start-new.ipynb'):\n !wget https://huggingface.co/viyi/sdwui/resolve/main/sdwui-start-new.ipynb -o log.log\n%run sdwui-start-new.ipynb","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 打包收藏文件夹 如果需要可以取消下面两行的注释\n# zipPath('$install_path/stable-diffusion-webui/log','log')\n# !mv {output_path}/log.tar {output_path}/log.tar.bak\n# createOrUpdateDataSet(f'{output_path}/log.tar.bak','sd-webui-log-bak')\n\n# 打包 这一行的结果是 压缩一个目录,并放在 output_path: /kaggle/working/ 目录下 名字是训练输出.tar\n# zipPath('$install_path/stable-diffusion-webui/textual_inversion','训练输出') \n# zipPath('$install_path/stable-diffusion-webui/outputs','outputs')\n\n# 打包venv并上传到数据集\n# zipPath('$install_path/stable-diffusion-webui/venv','venv')\n# !mv {output_path}/venv.tar /kaggle/working/venv.tar.bak\n# createOrUpdateDataSet('/kaggle/working/venv.tar.bak','sd-webui-venv')\n\n# 打包命令参考,--exclude 可以排除不需要打包的目录\n# !tar -cf $output_path/webui.tar.bak --exclude=venv --exclude=extensions -C /kaggle/stable-diffusion-webui/ .","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 使用帮助\n---\n**代码块不能删除也不能调换顺序,如果出现变量未定义,请检查是否按顺序执行了代码块**\n\n---\n\n## kaggle账号\n- 注册账号需要手机号,国内手机号也行,如果点击注册后没反应,估计是需要梯子,用于人机验证\n- 注册后点此笔记的 **Copy & Edit** 按钮就进到编辑界面\n\n## 准备工作\n1. 右侧面板 **Settings/ACCELERATOR** 需要选择GPU **T4x2**出图更快,且会自动开启两个webui\n2. 右侧面板 **Settings/LANGUAGE** 需要选择Python\n2. 右侧面板 **Settings/PERSISTENCE** 建议选择 Files only **作用是保存Outpot目录内的文件**\n3. 右侧面板 **Settings/ENVIRONMENT** 建议不改这个配置,使用当前默认值就行\n4. 右侧面板 **Settings/INTERNET** 需要打开 用于联网,没网跑不起来的啊\n\n## 启动\n#### 启动方式一 **直接点击页面上边的 RunAll**\n- 在没有关闭电源的情况下,后几次点击RunAll的输出在页面上端 (其实没有必要了,之前不知道代码块可以收起,很烦滚动到页面底端才能看见输出)\n- 手机端可能会出现页面上边的工具栏不显示的情况,左侧菜单按钮里也有相关的操作\n- 长时间不操作页面会导致脚本停止 (应该是40分钟吧)\n\n#### 启动方式二 **使用页面上边的 Save Version 后台运行**\n- 后台运行不用担心长时间不操作脚本停止\n- Version Type 选择 **Save & Run All**\n- 在Save Version弹窗里需要选择使用**GPU**环境 (Advanced Settings 里最后一个选项)\n- 后台运行的输出的图片可以在运行结束后下载(但是保存时间有限制,我就经常下不到,不够问题���大,喜欢的图在生成后就下载了)\n- 如果你需要下载运行后的图片,请不要把安装目录修改到 /kaggle/working 这个目录下,因为没有写打包功能,下载只能下载整个输出目录,也就是 /kaggle/working 目录\n\n## 访问\n- 如果你使用了ngrok或者frpc,可以访问你这两对应的地址\n- 如果你不知道你的ngrok或者frpc的地址可以在控制台(页面最下方Console)的输出里面查看\n- 使用Run All方式启动,控制台在启动完成后会输出访问网址,网址内容包含**gradio.live**,可以在页面中搜索快速找到\n- 如果使用Save Verson的方式启动,点击左下角的**View Active Events**点击刚刚启动的脚步,在**Log**里找访问网址\n- 一般情况下第一次启动此脚本需要等待kaggle下载模型文件,进度在页面上方\n- 第二次及以后(不增加新的文件)需要3到5分钟\n\n## 增加模型\n1. 先创建数据集,也就是dataset\n2. 创建时需要添加文件,选择自己的模型文件就行\n3. 同类型文件放相同的数据集里面,一个数据集也不要太大\n4. 可以在dataset搜索其他人上传的模型\n5. 通过右侧的 **Add Data** 按钮选择已经上传的模型文件或者别人上传的模型文件\n - input 下面的列表就是模型文件,可以点击名称后面的复制按钮复制路径\n6. 将模型路径放在配置里的对应配置里即可,支持文件夹和文件路径,参考 **modelDirs**\n - 如果目录里还有子目录也是需要加载的,可以用*表示子目录 例子:比如Loras目录下还有角色、画风、涩涩的文件夹,那路径里写成 '/kaggle/input/Loras/*'就可以加载子目录里面的文件了\n - 模型加载使用的文件链接方式,如果你融模型的时候新模型名字和原有模型名字一样,会出现不能修改只读文件的错误\n - 同理,直接对模型做编辑的工具可能也会出现相同的错误\n \n \n- **为了提高启动速度,导致切换模型过程较慢,点击切换模型后进度条大概率会一直存在,但模型在1分半左右基本能加载完。** \n- **受到kaggle内存大小的影响,切换多个模型后大概率爆内存导致停止运行**\n \n**下边的配置项都写了对应配置的作用和使用说明,不理解的话也不用改,用默认的就好**\n\n## 下载文件\n#### 方式一\n- 在浏览器直接下 比如你需要下载的文件路径在 /kaggle/stable-diffusion-webui/models/Lora/dow_a.safetensors\n - 比如你需要下载的文件路径在 /kaggle/stable-diffusion-webui/models/Lora/dow_a.safetensors\n - 你的访问地址是 https://123123123.gradio.live\n - 则可以在浏览器输入 https://123123123.gradio.live/file=/kaggle/stable-diffusion-webui/models/Lora/dow_a.safetensors 下载你的文件\n \n#### 方式二\n- 复制到Output目录下载 仅支持使用Run All方式运行的\n - 比如你需要下载的文件路径在 /kaggle/stable-diffusion-webui/models/Lora/dow_a.safetensors\n - 先停止笔记本(不是关机,是停止)\n - 然后新建一个代码块,在里面输入 !cp -f /kaggle/stable-diffusion-webui/models/Lora/dow_a.safetensors /kaggle/working/\n - 或者 新建一个代码块,在里面输入 !cp -f \\$install_path/stable-diffusion-webui/models/Lora/dow_a.safetensors /kaggle/working/\n - 你可能需要拼接路径 如果是在webui里面看到的路径,且路径里面没有带**stable-diffusion-webui**\n - 拼接方式是 **\\$install_path/stable-diffusion-webui** + **文件路径** 拼成类似前一条的样子\n - 就可以在右侧列表的Output目录看见复制出来的文件,点击下载即可\n \n#### 方式三\n- 开启链接输出目录的配置 (配置在第二个代码块,通过搜索**配置文件链接**快速查找)\n - 此方法会把已知的三个训练输出目录链接到Output目录下,直接去下载即可(两种启动方式都可以用)\n - 如果有新的目录需要链接,可以参考着自己写或者联系我\n \n#### 方式四\n- 将安装目录改到输出目录(配置在第二个代码块,通过搜索**安装目录**快速查找)\n - 此方式会把所有文件都放在安装目录,找到并下载即可\n - 如果使用这个方式,右侧的设置里**PERSISTENCE**这个设置项建议选No pensistence。如果选其他项,可能会出现关机特别慢的情况,因为需要上传输出目录的文件。\n\n## **一些可能没用的说明**\n- 配置说明 **True或者False**表示布尔值 **True**表示“**是**” **False**表示“**否**” 只有这两个值\n- 配置说明 **[]** 表示数组,里面可以存放内容,每个内容需要用**英语(半角)逗号**隔开\n- 配置说明 **''或者\"\"** 英语(半角)的双引号或者单引号包裹的内容是**字符串**,比如放在数组里面的路径就需要是一个字符串\n- 配置说明 **#** **#** 后面的内容是**注释**,是帮助性内容,对整个代���的执行不会有影响\n","metadata":{}},{"cell_type":"markdown","source":"# 更新记录\n#### 230901 v173\n- 更新了依赖版本,可以加载sdxl模型了\n- 增加代码块内容说明,希望有用\n\n#### 230812 v171\n- 把关闭半精度的参数注释了,这是之前写错的,注释后不容易爆内存\n- 增加默认模型的参数,用于指定模型启动时默认的模型\n\n#### 230726 v170\n- 更新了整个配置,可以更加自由的下载和加载文件\n- 删除了大部分参数\n\n#### 230726 v169\n- 增加了一个文件加载配置,可以自定义把文件或下载地址加载到指定目录,配置方式见 [ 其他文件列表 ]\n- 增加了一个配置,可以隐藏部分控制台输出,但隐藏不完全,没啥用\n\n#### 230719 v168\n- 增加了同步收藏文件夹到 huggingface 数据集的功能,仅同步收藏文件夹,如果同步所有图片也太浪费资源了\n\n#### 230716 v167\n- 账号解封了\n- 已经更新为精简自动更新版,主要逻辑分离存放到 [huggingface](https://huggingface.co/viyi/sdwui),这边基本上不再需要更新\n- 如果增加了新功能需要新的配置,可以在输出内容的最前面查看到(暂定)\n\n#### 230302 v165\n- 可以修改disableShared=True来使用pm2启动,做到爆内存自动重启(需要使用frpc或者ngrok代理,否则无法访问界面)\n\n#### 230228 v156\n- 移除了koishi的相关功能 如需使用,可查看 [sd-webui-koishi](https://www.kaggle.com/code/yiyiooo/sd-webui-koishi)\n\n#### 230227 v147\n- 增加了nginx做反向代理,现在可以使用一个ngrok地址访问多个服务了 功能在版本156移除\n\n#### 230225 v139\n- 可以加载ssl证书,启动https的隧道了\n\n#### 230224 v134\n- 可以自动修改frp的本地端口\n\n#### 230224 v128\n- 修复默认模型文件不存在时不能启动的问题\n- 修复了多线程导致依赖等内容安装位置错乱的问题\n- 修复了第一次启动会更新koishi数据对应的数据集问题\n- 增加了配置检查功能,对一些配置项做了提示\n- 增加了可配置webui端口功能,现在可以配置webui、froc、ngrok的端口了\n\n#### 230223 v126\n- 修复了仅适用koishi数据目录无法启动koishi的问题\n- 修改了部分文档\n\n#### 230223 v124\n- 修复使用多线程后出现的文件安装下载目录失败的问题\n- 修复使用多线程后文件目录错乱问题\n\n#### 230222 v123\n- 使用多线程进行安装,节省安装时间\n\n#### 230222 v122\n- 更改了默认配置,现在训练的输出可以在Output下面查看了\n\n#### 230222 v118\n- 增加了自动上传koishi的数据到数据集且能自动下载的功能\n - 自动上传的数据集优先级高于手动上传的\n - 上一个版本的数据集与当前版本的目录结构有差异,如果更新后需要修改配置\n \n#### 230121 v111\n- 增加了koishi的部署相关功能 功能在版本156移除\n\n#### 230220 v110\n- 增加了ControlNet插件的一些说明\n\n#### 230220 v109\n- 修复第二次Run all时不能切换到新的frpc配置问题\n- 增加更新记录,用于记录每次更新 ","metadata":{}}]}
|
|
|
|
|
|
venv.zip
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:449336282c7aa4142cdc5a4f2f653027018ce3396bd22e9b39ae461330c9b18a
|
| 3 |
+
size 2505464937
|