Error after custom upgrade dependency
dockerfile: `# ================================================================
📦 0.1 基础镜像:pytorch:2.7.0-cuda12.8-cudnn9-devel
================================================================
FROM pytorch/pytorch:2.7.0-cuda12.8-cudnn9-devel
===============================
🚩 设置时区(上海)
===============================
ENV TZ=Asia/Shanghai
RUN echo "🔧 正在设置时区为 $TZ..." &&
ln -snf /usr/share/zoneinfo/$TZ /etc/localtime &&
echo $TZ > /etc/timezone &&
echo "✅ 时区已成功设置:$(date)"
===============================
🚩 安装系统依赖 & CUDA 工具链
===============================
RUN echo -e "🔧 开始安装系统依赖和 CUDA 开发工具...\n" &&
apt-get update && apt-get upgrade -y &&
apt-get install -y --no-install-recommends
wget git git-lfs curl procps
libgl1 libgl1-mesa-glx libglvnd0
libglib2.0-0 libsm6 libxrender1 libxext6
xvfb build-essential cmake bc
libgoogle-perftools-dev
apt-transport-https htop nano bsdmainutils
lsb-release software-properties-common &&
echo -e "✅ 基础系统依赖安装完成\n" &&
apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
===============================
✅ 验证环境完整性
===============================
RUN echo "🔍 验证 CUDA 编译器版本:" && nvcc --version &&
python3 -c "import torch; print('✔️ torch:', torch.version, '| CUDA:', torch.version.cuda)"
===============================
🚩 创建非 root 用户 webui
===============================
RUN echo "🔧 正在创建非 root 用户 webui..." &&
useradd -m webui &&
echo "✅ 用户 webui 创建完成"
===============================
🚩 设置工作目录 + 拷贝启动脚本
===============================
WORKDIR /app
COPY run.sh /app/run.sh
RUN echo "🔧 正在创建工作目录并设置权限..." &&
chmod +x /app/run.sh &&
mkdir -p /app/webui &&
chown -R webui:webui /app/webui &&
echo "✅ 工作目录设置完成"
===============================
🚩 切换至非 root 用户 webui
===============================
USER webui
WORKDIR /app/webui
RUN echo "✅ 已成功切换至用户:$(whoami)" &&
echo "✅ 当前工作目录为:$(pwd)"
===============================
🚩 检查 Python 环境完整性
===============================
RUN echo "🔎 Python 环境自检开始..." &&
python3 --version &&
pip3 --version &&
python3 -m venv --help > /dev/null &&
echo "✅ Python、pip 和 venv 已正确安装并通过检查" ||
echo "⚠️ Python 环境完整性出现问题,请排查!"
===============================
🚩 容器启动入口
===============================
ENTRYPOINT ["/app/run.sh"]`
run.sh: `#!/bin/bash
set -e set -o pipefail
日志配置
==================================================
LOG_FILE="/app/webui/launch.log"
若日志文件存在则清空内容
if [[ -f "$LOG_FILE" ]]; then echo "" > "$LOG_FILE" fi
确保日志目录存在
mkdir -p "$(dirname "$LOG_FILE")"
将所有标准输出和错误输出重定向到文件和控制台
exec > >(tee -a "$LOG_FILE") 2>&1
echo "==================================================" echo "🚀 [0] 启动脚本 Stable Diffusion WebUI" echo "=================================================="
---------------------------------------------------
系统环境自检
---------------------------------------------------
echo "🛠️ [0.5] 系统环境自检..."
Python 检查
if command -v python3 &>/dev/null; then echo "✅ Python3 版本: $(python3 --version)" else echo "❌ 未找到 Python3,脚本将无法运行!" exit 1 fi
pip 检查
if command -v pip3 &>/dev/null; then echo "✅ pip3 版本: $(pip3 --version)" else echo "❌ pip3 未安装!请在 Dockerfile 中添加 python3-pip" exit 1 fi
CUDA & GPU 检查(使用 nvidia-smi 原始图表)
if command -v nvidia-smi &>/dev/null; then echo "✅ nvidia-smi 检测成功,GPU 原始信息如下:" echo "--------------------------------------------------" nvidia-smi echo "--------------------------------------------------" else echo "⚠️ 未检测到 nvidia-smi(可能无 GPU 或驱动未安装)" fi
容器检测
if [ -f "/.dockerenv" ]; then echo "📦 正在容器中运行" else echo "🖥️ 非容器环境" fi
echo "👤 当前用户: $(whoami)"
if [ -w "/app/webui" ]; then echo "✅ /app/webui 可写" else echo "❌ /app/webui 不可写,可能会导致运行失败" exit 1 fi
echo "✅ 系统环境自检通过"
---------------------------------------------------
环境变量设置
---------------------------------------------------
echo "🔧 [1] 解析 UI 与 ARGS 环境变量..." UI="${UI:-forge}" ARGS="${ARGS:---xformers --api --listen --enable-insecure-extension-access --theme dark}" echo "🧠 UI=${UI}" echo "🧠 ARGS=${ARGS}"
echo "🔧 [2] 解析下载开关环境变量 (默认全部启用)..."
解析全局下载开关
ENABLE_DOWNLOAD_ALL="${ENABLE_DOWNLOAD:-true}"
解析独立的模型和资源类别开关
ENABLE_DOWNLOAD_EXTS="${ENABLE_DOWNLOAD_EXTS:-$ENABLE_DOWNLOAD_ALL}" ENABLE_DOWNLOAD_MODEL_SD15="${ENABLE_DOWNLOAD_MODEL_SD15:-$ENABLE_DOWNLOAD_ALL}" ENABLE_DOWNLOAD_MODEL_SDXL="${ENABLE_DOWNLOAD_MODEL_SDXL:-$ENABLE_DOWNLOAD_ALL}" ENABLE_DOWNLOAD_MODEL_FLUX="${ENABLE_DOWNLOAD_MODEL_FLUX:-$ENABLE_DOWNLOAD_ALL}" ENABLE_DOWNLOAD_VAE_FLUX="${ENABLE_DOWNLOAD_VAE_FLUX:-$ENABLE_DOWNLOAD_ALL}" ENABLE_DOWNLOAD_TE_FLUX="${ENABLE_DOWNLOAD_TE_FLUX:-$ENABLE_DOWNLOAD_ALL}" ENABLE_DOWNLOAD_CNET_SD15="${ENABLE_DOWNLOAD_CNET_SD15:-$ENABLE_DOWNLOAD_ALL}" ENABLE_DOWNLOAD_CNET_SDXL="${ENABLE_DOWNLOAD_CNET_SDXL:-$ENABLE_DOWNLOAD_ALL}" ENABLE_DOWNLOAD_CNET_FLUX="${ENABLE_DOWNLOAD_CNET_FLUX:-$ENABLE_DOWNLOAD_ALL}" ENABLE_DOWNLOAD_VAE="${ENABLE_DOWNLOAD_VAE:-$ENABLE_DOWNLOAD_ALL}" ENABLE_DOWNLOAD_LORAS="${ENABLE_DOWNLOAD_LORAS:-$ENABLE_DOWNLOAD_ALL}" ENABLE_DOWNLOAD_EMBEDDINGS="${ENABLE_DOWNLOAD_EMBEDDINGS:-$ENABLE_DOWNLOAD_ALL}" ENABLE_DOWNLOAD_UPSCALERS="${ENABLE_DOWNLOAD_UPSCALERS:-$ENABLE_DOWNLOAD_ALL}" ENABLE_DOWNLOAD_TE="${ENABLE_DOWNLOAD_TE:-$ENABLE_DOWNLOAD_ALL}" # 为 text_encoder 添加独立的开关
解析独立的镜像使用开关
USE_HF_MIRROR="${USE_HF_MIRROR:-false}" # 控制是否使用 hf-mirror.com USE_GIT_MIRROR="${USE_GIT_MIRROR:-false}" # 控制是否使用 gitcode.net
echo " - 下载总开关 (ENABLE_DOWNLOAD_ALL): ${ENABLE_DOWNLOAD_ALL}" echo " - 下载 Extensions (ENABLE_DOWNLOAD_EXTS): ${ENABLE_DOWNLOAD_EXTS}" echo " - 下载 Checkpoint SD1.5 (ENABLE_DOWNLOAD_MODEL_SD15): ${ENABLE_DOWNLOAD_MODEL_SD15}" echo " - 下载 Checkpoint SDXL (ENABLE_DOWNLOAD_MODEL_SDXL): ${ENABLE_DOWNLOAD_MODEL_SDXL}" echo " - 下载 Checkpoint FLUX (ENABLE_DOWNLOAD_MODEL_FLUX): ${ENABLE_DOWNLOAD_MODEL_FLUX}" echo " - 下载 VAE FLUX (ENABLE_DOWNLOAD_VAE_FLUX): ${ENABLE_DOWNLOAD_VAE_FLUX}" echo " - 下载 TE FLUX (ENABLE_DOWNLOAD_TE_FLUX): ${ENABLE_DOWNLOAD_TE_FLUX}" echo " - 下载 ControlNet SD1.5 (ENABLE_DOWNLOAD_CNET_SD15): ${ENABLE_DOWNLOAD_CNET_SD15}" echo " - 下载 ControlNet SDXL (ENABLE_DOWNLOAD_CNET_SDXL): ${ENABLE_DOWNLOAD_CNET_SDXL}" echo " - 下载 ControlNet FLUX (ENABLE_DOWNLOAD_CNET_FLUX): ${ENABLE_DOWNLOAD_CNET_FLUX}" echo " - 下载 通用 VAE (ENABLE_DOWNLOAD_VAE): ${ENABLE_DOWNLOAD_VAE}" echo " - 下载 LoRAs/LyCORIS (ENABLE_DOWNLOAD_LORAS): ${ENABLE_DOWNLOAD_LORAS}" echo " - 下载 Embeddings (ENABLE_DOWNLOAD_EMBEDDINGS): ${ENABLE_DOWNLOAD_EMBEDDINGS}" echo " - 下载 Upscalers (ENABLE_DOWNLOAD_UPSCALERS): ${ENABLE_DOWNLOAD_UPSCALERS}" echo " - 下载 Text Encoders (ENABLE_DOWNLOAD_TE): ${ENABLE_DOWNLOAD_TE}" # 输出 Text Encoder 的下载开关 echo " - 是否使用 HF 镜像 (USE_HF_MIRROR): ${USE_HF_MIRROR}" # (hf-mirror.com) echo " - 是否使用 Git 镜像 (USE_GIT_MIRROR): ${USE_GIT_MIRROR}" # (gitcode.net)
export NO_TCMALLOC=1 export PIP_EXTRA_INDEX_URL="https://download.pytorch.org/whl/cu128" export TORCH_COMMAND="pip install torch==2.7.0+cu128 --extra-index-url https://download.pytorch.org/whl/cu128"
预定义镜像地址 (如果需要可以从环境变量读取,但简单起见先硬编码)
HF_MIRROR_URL="https://hf-mirror.com" GIT_MIRROR_URL="https://gitcode.net" # 使用 https
---------------------------------------------------
设置 Git 源路径
---------------------------------------------------
echo "🔧 [3] 设置仓库路径与 Git 源..." if [ "$UI" = "auto" ]; then TARGET_DIR="/app/webui/sd-webui" REPO="https://github.com/AUTOMATIC1111/stable-diffusion-webui.git" elif [ "$UI" = "forge" ]; then TARGET_DIR="/app/webui/sd-webui-forge" REPO="https://github.com/lllyasviel/stable-diffusion-webui-forge.git" else echo "❌ Unknown UI: $UI" exit 1 fi echo "📁 目标目录: $TARGET_DIR" echo "🌐 GIT 源: $REPO"
---------------------------------------------------
克隆/更新仓库
---------------------------------------------------
if [ -d "$TARGET_DIR/.git" ]; then echo "🔁 仓库已存在,执行 git pull..." git -C "$TARGET_DIR" pull --ff-only || echo "⚠️ Git pull failed" else echo "📥 Clone 仓库..." git clone "$REPO" "$TARGET_DIR" chmod +x "$TARGET_DIR/webui.sh" fi
---------------------------------------------------
requirements_versions.txt 修复
---------------------------------------------------
echo "🔧 [5] 补丁修正 requirements_versions.txt..." REQ_FILE="$TARGET_DIR/requirements_versions.txt" touch "$REQ_FILE"
add_or_replace_requirement() { local package="$1" local version="$2" if grep -q "^$package==" "$REQ_FILE"; then echo "🔁 替换: $package==... → $package==$version" sed -i "s|^$package==.*|$package==$version|" "$REQ_FILE" else echo "➕ 追加: $package==$version" echo "$package==$version" >> "$REQ_FILE" fi }
推荐依赖版本
add_or_replace_requirement "torch" "2.7.0" add_or_replace_requirement "xformers" "0.0.30" add_or_replace_requirement "torchdiffeq" "0.2.3" add_or_replace_requirement "torchsde" "0.2.6" add_or_replace_requirement "protobuf" "4.25.3" add_or_replace_requirement "pydantic" "2.6.4" add_or_replace_requirement "open-clip-torch" "2.24.0" add_or_replace_requirement "diffusers" "0.32.0" add_or_replace_requirement "dill" "0.4.0" add_or_replace_requirement "onnxruntime-gpu" "1.17.1" add_or_replace_requirement "controlnet-aux" "0.0.10"
check_gitpython_version() { local required_version="3.1.41" if python3 -c "import git, sys; from packaging import version; sys.exit(0) if version.parse(git.version) >= version.parse('$required_version') else sys.exit(1)" 2>/dev/null; then echo "✅ GitPython >= $required_version 已存在" else echo "🔧 添加 GitPython==$required_version" add_or_replace_requirement "GitPython" "$required_version" fi } check_gitpython_version
echo "📦 最终依赖列表如下:" grep -E '^(torch|xformers|diffusers|transformers|torchdiffeq|torchsde|GitPython|protobuf|pydantic|open-clip-torch)=' "$REQ_FILE" | sort
---------------------------------------------------
Python 虚拟环境
---------------------------------------------------
cd "$TARGET_DIR" chmod -R 777 .
echo "🐍 [6] 虚拟环境检查..."
if [ ! -x "venv/bin/activate" ]; then echo "📦 创建 venv..." python3 -m venv venv
echo "🔧 激活 venv..."
shellcheck source=/dev/null
source venv/bin/activate
echo "🔧 [6.1.1] 安装工具包:insightface, huggingface_hub[cli]..."
---------------------------------------------------
安装工具包(insightface 和 huggingface-cli)
---------------------------------------------------
for pkg in insightface "huggingface_hub[cli]"; do echo "🔍 检查 $pkg 是否已安装..." base_pkg=$(echo "$pkg" | cut -d '[' -f 1) if python -m pip show "$base_pkg" | grep -q "Version"; then echo "✅ $pkg 已安装,跳过安装" else echo "📦 安装 $pkg..." python -m pip install --upgrade "$pkg" fi done
echo "📦 venv 安装完成 ✅" deactivate
else echo "✅ venv 已存在,跳过创建和安装" fi
echo "🔧 激活 venv..."
shellcheck source=/dev/null
source venv/bin/activate
==================================================
Token 处理 (Hugging Face, Civitai)
==================================================
步骤号顺延为 [10]
echo "🔐 [10] 处理 API Tokens (如果已提供)..."
处理 Hugging Face Token (如果环境变量已设置)
if [[ -n "$HUGGINGFACE_TOKEN" ]]; then echo " - 检测到 HUGGINGFACE_TOKEN,尝试使用 huggingface-cli 登录..."
检查 huggingface-cli 命令是否存在 (应由 huggingface_hub[cli] 提供)
if command -v huggingface-cli &>/dev/null; then # 正确用法:将 token 作为参数传递给 --token huggingface-cli login --token "$HUGGINGFACE_TOKEN" --add-to-git-credential # 检查命令执行是否成功 if [ $? -eq 0 ]; then echo " - ✅ Hugging Face CLI 登录成功。" else # 登录失败通常不会是致命错误,只记录警告 echo " - ⚠️ Hugging Face CLI 登录失败。请检查 Token 是否有效、是否过期或 huggingface-cli 是否工作正常。" fi else echo " - ⚠️ 未找到 huggingface-cli 命令,无法登录。请确保依赖 'huggingface_hub[cli]' 已正确安装在 venv 中。" fi else
如果未提供 Token
echo " - ⏭️ 未设置 HUGGINGFACE_TOKEN 环境变量,跳过 Hugging Face 登录。" fi
检查 Civitai API Token
if [[ -n "$CIVITAI_API_TOKEN" ]]; then echo " - ✅ 检测到 CIVITAI_API_TOKEN (长度: ${#CIVITAI_API_TOKEN})。" else echo " - ⏭️ 未设置 CIVITAI_API_TOKEN 环境变量。" fi deactivate
---------------------------------------------------
创建目录
---------------------------------------------------
echo "📁 [7] 初始化项目目录结构..." mkdir -p extensions models models/ControlNet outputs
---------------------------------------------------
网络测试
---------------------------------------------------
echo "🌐 [8] 网络连通性测试..." if curl -s --connect-timeout 3 https://www.google.com > /dev/null; then NET_OK=true echo "✅ 网络连通 (Google 可访问)" else NET_OK=false echo "⚠️ 无法访问 Google,部分资源或插件可能无法下载" fi
==================================================
资源下载 (使用 resources.txt)
==================================================
echo "📦 [9] 处理资源下载 (基于 $PWD/resources.txt 和下载开关)..." RESOURCE_PATH="$PWD/resources.txt"
✅ 然后继续执行原来的资源遍历逻辑
echo " - 开始处理 resources.txt 中的条目..."
检查资源文件是否存在,如果不存在则尝试下载默认版本
if [ ! -f "$RESOURCE_PATH" ]; then
指定默认资源文件的 URL
DEFAULT_RESOURCE_URL="https://raw.githubusercontent.com/amDosion/forage/main/resources.txt" echo " - 未找到本地 resources.txt,尝试从 ${DEFAULT_RESOURCE_URL} 下载..."
使用 curl 下载,确保失败时不输出错误页面 (-f),静默 (-s),跟随重定向 (-L)
curl -fsSL -o "$RESOURCE_PATH" "$DEFAULT_RESOURCE_URL" if [ $? -eq 0 ]; then echo " - ✅ 默认 resources.txt 下载成功。" else echo " - ❌ 下载默认 resources.txt 失败。请手动将资源文件放在 ${RESOURCE_PATH} 或检查网络/URL。" # 创建一个空文件以避免后续读取错误,但不会下载任何内容 touch "$RESOURCE_PATH" echo " - 已创建空的 resources.txt 文件以继续,但不会下载任何资源。" fi else echo " - ✅ 使用本地已存在的 resources.txt: ${RESOURCE_PATH}" fi
✅ ✅ ✅ 添加此段:记录 resources.txt 中声明的插件路径
declare -A RESOURCE_DECLARED_PATHS
while IFS=, read -r target_path source_url || [[ -n "$target_path" ]]; do target_path=$(echo "$target_path" | xargs) source_url=$(echo "$source_url" | xargs)
[[ "$target_path" =~ ^#.*$ || -z "$target_path" || -z "$source_url" ]] && continue
如果是 extensions 路径则加入映射
if [[ "$target_path" == extensions/* ]]; then full_path="$PWD/$target_path" RESOURCE_DECLARED_PATHS["$full_path"]=1 fi done < "$RESOURCE_PATH"
✅✅✅ 检查本地 extensions 目录中未在 resources.txt 中声明的插件
EXT_DIR="$PWD/extensions" if [ -d "$EXT_DIR" ]; then echo "🧹 检查本地 extensions/ 中未声明的插件..." for existing_path in "$EXT_DIR"/*; do if [ -d "$existing_path" ]; then if [[ -z "${RESOURCE_DECLARED_PATHS[$existing_path]}" ]]; then echo " - ⛔ 插件未在 resources.txt 声明,跳过处理: $(basename "$existing_path")" fi fi done fi
定义函数:克隆或更新 Git 仓库 (支持独立 Git 镜像开关 + 资源控制)
clone_or_update_repo() { # $1: 目标目录, $2: 原始仓库 URL local dir="$1" repo_original="$2" local dirname local repo_url # URL to be used for cloning/pulling local full_path="$PWD/$dir"
dirname=$(basename "$dir")
# ✅ 新增:只允许处理 resources.txt 中声明的插件路径
if [[ -n "$RESOURCE_PATH" && -n "${RESOURCE_DECLARED_PATHS[$full_path]}" ]]; then
: # 路径被声明,继续
else
echo " - ⚠️ 插件未在 resources.txt 中声明,跳过 Git 操作: $dirname"
return
fi
# 检查是否启用了 Git 镜像以及是否是 GitHub URL
if [[ "$USE_GIT_MIRROR" == "true" && "$repo_original" == "https://github.com/"* ]]; then
local git_mirror_host
git_mirror_host=$(echo "$GIT_MIRROR_URL" | sed 's|https://||; s|http://||; s|/.*||')
repo_url=$(echo "$repo_original" | sed "s|github.com|$git_mirror_host|")
echo " - 使用镜像转换 (Git): $repo_original -> $repo_url"
else
repo_url="$repo_original"
fi
# 检查扩展下载开关
if [[ "$ENABLE_DOWNLOAD_EXTS" != "true" ]]; then
if [ -d "$dir" ]; then
echo " - ⏭️ 跳过更新扩展/仓库 (ENABLE_DOWNLOAD_EXTS=false): $dirname"
else
echo " - ⏭️ 跳过克隆扩展/仓库 (ENABLE_DOWNLOAD_EXTS=false): $dirname"
fi
return
fi
# 尝试更新或克隆
if [ -d "$dir/.git" ]; then
echo " - 🔄 更新扩展/仓库: $dirname (from $repo_url)"
(cd "$dir" && git pull --ff-only) || echo " ⚠️ Git pull 失败: $dirname (可能存在本地修改或网络问题)"
elif [ ! -d "$dir" ]; then
echo " - 📥 克隆扩展/仓库: $repo_url -> $dirname (完整克隆)"
git clone --recursive "$repo_url" "$dir" || echo " ❌ Git clone 失败: $dirname (检查 URL: $repo_url 和网络)"
else
echo " - ✅ 目录已存在但非 Git 仓库,跳过 Git 操作: $dirname"
fi
}
定义函数:下载文件 (支持独立 HF 镜像开关)
download_with_progress() { # $1: 输出路径, $2: 原始 URL, $3: 资源类型描述, $4: 对应的下载开关变量值 local output_path="$1" url_original="$2" type="$3" enabled_flag="$4" local filename local download_url # URL to be used for downloading
filename=$(basename "$output_path")
# 检查下载开关
if [[ "$enabled_flag" != "true" ]]; then
echo " - ⏭️ 跳过下载 ${type} (开关 '$enabled_flag' != 'true'): $filename"
return
fi
# 检查网络
if [[ "$NET_OK" != "true" ]]; then
echo " - ❌ 跳过下载 ${type} (网络不通): $filename"
return
fi
# 检查是否启用了 HF 镜像以及是否是 Hugging Face URL
# 使用步骤 [2] 中定义的 HF_MIRROR_URL
if [[ "$USE_HF_MIRROR" == "true" && "$url_original" == "https://huggingface.co/"* ]]; then
# 替换 huggingface.co 为镜像地址
download_url=$(echo "$url_original" | sed "s|https://huggingface.co|$HF_MIRROR_URL|")
echo " - 使用镜像转换 (HF): $url_original -> $download_url"
else
# 使用原始 URL
download_url="$url_original"
fi
# 检查文件是否已存在
if [ ! -f "$output_path" ]; then
echo " - ⬇️ 下载 ${type}: $filename (from $download_url)"
mkdir -p "$(dirname "$output_path")"
# 执行下载
wget --progress=bar:force:noscroll --timeout=120 -O "$output_path" "$download_url"
# 检查结果
if [ $? -ne 0 ]; then
echo " ❌ 下载失败: $filename from $download_url (检查 URL 或网络)"
rm -f "$output_path"
else
echo " ✅ 下载完成: $filename"
fi
else
echo " - ✅ 文件已存在,跳过下载 ${type}: $filename"
fi
}
---------------------------------------------------
插件黑名单
---------------------------------------------------
SKIP_LIST=( "$PWD/extensions/stable-diffusion-aws-extension" "$PWD/extensions/sd_dreambooth_extension" "$PWD/extensions/stable-diffusion-webui-aesthetic-image-scorer" )
函数:检查目标路径是否应跳过
should_skip() { local dir_to_check="$1" for skip_dir in "${SKIP_DIRS[@]}"; do # 完全匹配路径 if [[ "$dir_to_check" == "$skip_dir" ]]; then return 0 # 0 表示应该跳过 (Bash true) fi done return 1 # 1 表示不应该跳过 (Bash false) }
echo " - 开始处理 resources.txt 中的条目..."
逐行读取 resources.txt 文件 (逗号分隔: 目标路径,源URL)
while IFS=, read -r target_path source_url || [[ -n "$target_path" ]]; do
清理路径和 URL 的前后空格
target_path=$(echo "$target_path" | xargs) source_url=$(echo "$source_url" | xargs)
跳过注释行 (# 开头) 或空行 (路径或 URL 为空)
[[ "$target_path" =~ ^#.*$ || -z "$target_path" || -z "$source_url" ]] && continue
在目标路径前加上 $PWD
full_target_path="$PWD/$target_path"
检查是否在黑名单中
if should_skip "$full_target_path"; then echo " - ⛔ 跳过黑名单条目: $full_target_path" continue # 处理下一行 fi
根据目标路径判断资源类型并调用相应下载函数及正确的独立开关
case "$full_target_path" in # 1. Extensions "$PWD/extensions/"*) clone_or_update_repo "$target_path" "$source_url" # Uses ENABLE_DOWNLOAD_EXTS internally ;;
# 2. Stable Diffusion Checkpoints
"$PWD/models/Stable-diffusion/SD1.5/"*)
download_with_progress "$target_path" "$source_url" "SD 1.5 Checkpoint" "$ENABLE_DOWNLOAD_MODEL_SD15"
;;
"$PWD/models/Stable-diffusion/XL/"*)
download_with_progress "$target_path" "$source_url" "SDXL Checkpoint" "$ENABLE_DOWNLOAD_MODEL_SDXL"
;;
"$PWD/models/Stable-diffusion/flux/"*)
download_with_progress "$target_path" "$source_url" "FLUX Checkpoint" "$ENABLE_DOWNLOAD_MODEL_FLUX"
;;
"$PWD/models/Stable-diffusion/*") # Fallback
echo " - ❓ 处理未分类 Stable Diffusion 模型: $full_target_path (默认使用 SD1.5 开关)"
download_with_progress "$target_path" "$source_url" "SD 1.5 Checkpoint (Fallback)" "$ENABLE_DOWNLOAD_MODEL_SD15"
;;
# 3. VAEs
"$PWD/models/VAE/flux-*.safetensors") # FLUX Specific VAE
download_with_progress "$target_path" "$source_url" "FLUX VAE" "$ENABLE_DOWNLOAD_VAE_FLUX" # Use specific FLUX VAE switch
;;
"$PWD/models/VAE/*") # Other VAEs
download_with_progress "$target_path" "$source_url" "VAE Model" "$ENABLE_DOWNLOAD_VAE"
;;
# 4. Text Encoders (Currently FLUX specific)
"$PWD/models/text_encoder/"*)
download_with_progress "$target_path" "$source_url" "Text Encoder" "$ENABLE_DOWNLOAD_TE"
;;
# 5. ControlNet Models
"$PWD/models/ControlNet/"*)
filename=$(basename "$target_path")
if [[ "$filename" == control_v11* ]]; then
# 属于 SD 1.5 的 ControlNet 模型
download_with_progress "$target_path" "$source_url" "ControlNet SD 1.5" "$ENABLE_DOWNLOAD_CNET_SD15"
elif [[ "$filename" == *sdxl* || "$filename" == *SDXL* ]]; then
# 属于 SDXL 的 ControlNet 模型
download_with_progress "$target_path" "$source_url" "ControlNet SDXL" "$ENABLE_DOWNLOAD_CNET_SDXL"
elif [[ "$filename" == flux-* || "$filename" == *flux* ]]; then
# 属于 FLUX 的 ControlNet 模型
download_with_progress "$target_path" "$source_url" "ControlNet FLUX" "$ENABLE_DOWNLOAD_CNET_FLUX"
else
echo " - ❓ 未识别 ControlNet 模型类别: $filename,默认作为 SD1.5 处理"
download_with_progress "$target_path" "$source_url" "ControlNet SD 1.5 (Fallback)" "$ENABLE_DOWNLOAD_CNET_SD15"
fi
;;
# 6. LoRA and related models
"$PWD/models/Lora/*" | "$PWD/models/LyCORIS/*" | "$PWD/models/LoCon/*")
download_with_progress "$target_path" "$source_url" "LoRA/LyCORIS" "$ENABLE_DOWNLOAD_LORAS"
;;
# 7. Embeddings / Textual Inversion
"$PWD/models/TextualInversion/*" | "$PWD/embeddings/*")
download_with_progress "$target_path" "$source_url" "Embedding/Textual Inversion" "$ENABLE_DOWNLOAD_EMBEDDINGS"
;;
# 8. Upscalers
"$PWD/models/Upscaler/*" | "$PWD/models/ESRGAN/*")
download_with_progress "$target_path" "$source_url" "Upscaler Model" "$ENABLE_DOWNLOAD_UPSCALERS"
;;
# 9. Fallback for any other paths
*)
if [[ "$source_url" == *.git ]]; then
echo " - ❓ 处理未分类 Git 仓库: $full_target_path (默认使用 Extension 开关)"
clone_or_update_repo "$target_path" "$source_url" # Uses ENABLE_DOWNLOAD_EXTS internally
elif [[ "$source_url" == http* ]]; then
echo " - ❓ 处理未分类文件下载: $full_target_path (默认使用 SD1.5 Model 开关)"
download_with_progress "$target_path" "$source_url" "Unknown Model/File" "$ENABLE_DOWNLOAD_MODEL_SD15"
else
echo " - ❓ 无法识别的资源类型或无效 URL: target='$target_path', source='$source_url'"
fi
;;
esac # 结束 case done < "$RESOURCE_PATH" # 从资源文件读取
---------------------------------------------------
🔥 启动最终服务(FIXED!)
---------------------------------------------------
echo "🚀 [11] 所有准备就绪,启动 webui.sh ..."
exec bash webui.sh $ARGS`
日志如下: launch.log Using xformers cross attention Using xformers attention for VAE reading metadata for /app/webui/sd-webui-forge/models/Stable-diffusion/v1-5-pruned-emaonly.safetensors: OperationalError Traceback (most recent call last): File "/app/webui/sd-webui-forge/modules/sd_models.py", line 89, in init self.metadata = cache.cached_data_for_file('safetensors-metadata', "checkpoint/" + name, filename, read_metadata) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/app/webui/sd-webui-forge/modules/cache.py", line 119, in cached_data_for_file existing_cache[title] = entry ~~~~~~~~~~~~~~^^^^^^^ File "/app/webui/sd-webui-forge/venv/lib/python3.11/site-packages/diskcache/core.py", line 823, in setitem self.set(key, value, retry=True) File "/app/webui/sd-webui-forge/venv/lib/python3.11/site-packages/diskcache/core.py", line 808, in set self._row_insert(db_key, raw, now, columns) File "/app/webui/sd-webui-forge/venv/lib/python3.11/site-packages/diskcache/core.py", line 857, in _row_insert sql( sqlite3.OperationalError: no such column: "size" - should this be a string literal in single-quotes?
reading metadata for /app/webui/sd-webui-forge/models/Stable-diffusion/麦橘超然majicFlus_v1.safetensors: OperationalError Traceback (most recent call last): File "/app/webui/sd-webui-forge/modules/sd_models.py", line 89, in init self.metadata = cache.cached_data_for_file('safetensors-metadata', "checkpoint/" + name, filename, read_metadata) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/app/webui/sd-webui-forge/modules/cache.py", line 119, in cached_data_for_file existing_cache[title] = entry ~~~~~~~~~~~~~~^^^^^^^ File "/app/webui/sd-webui-forge/venv/lib/python3.11/site-packages/diskcache/core.py", line 823, in setitem self.set(key, value, retry=True) File "/app/webui/sd-webui-forge/venv/lib/python3.11/site-packages/diskcache/core.py", line 808, in set self._row_insert(db_key, raw, now, columns) File "/app/webui/sd-webui-forge/venv/lib/python3.11/site-packages/diskcache/core.py", line 857, in _row_insert sql( sqlite3.OperationalError: no such column: "size" - should this be a string literal in single-quotes?
ControlNet preprocessor location: /app/webui/sd-webui-forge/models/ControlNetPreprocessor [-] ADetailer initialized. version: 25.3.0, num models: 10 sd-webui-prompt-all-in-one background API service started successfully. Tag Autocomplete: Could not locate model-keyword extension, Lora trigger word completion will be limited to those added through the extra networks menu. reading metadata for /app/webui/sd-webui-forge/models/Stable-diffusion/v1-5-pruned-emaonly.safetensors: OperationalError Traceback (most recent call last): File "/app/webui/sd-webui-forge/modules/sd_models.py", line 89, in init self.metadata = cache.cached_data_for_file('safetensors-metadata', "checkpoint/" + name, filename, read_metadata) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/app/webui/sd-webui-forge/modules/cache.py", line 119, in cached_data_for_file existing_cache[title] = entry ~~~~~~~~~~~~~~^^^^^^^ File "/app/webui/sd-webui-forge/venv/lib/python3.11/site-packages/diskcache/core.py", line 823, in setitem self.set(key, value, retry=True) File "/app/webui/sd-webui-forge/venv/lib/python3.11/site-packages/diskcache/core.py", line 808, in set self._row_insert(db_key, raw, now, columns) File "/app/webui/sd-webui-forge/venv/lib/python3.11/site-packages/diskcache/core.py", line 857, in _row_insert sql( sqlite3.OperationalError: no such column: "size" - should this be a string literal in single-quotes?
reading metadata for /app/webui/sd-webui-forge/models/Stable-diffusion/麦橘超然majicFlus_v1.safetensors: OperationalError Traceback (most recent call last): File "/app/webui/sd-webui-forge/modules/sd_models.py", line 89, in init self.metadata = cache.cached_data_for_file('safetensors-metadata', "checkpoint/" + name, filename, read_metadata) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/app/webui/sd-webui-forge/modules/cache.py", line 119, in cached_data_for_file existing_cache[title] = entry ~~~~~~~~~~~~~~^^^^^^^ File "/app/webui/sd-webui-forge/venv/lib/python3.11/site-packages/diskcache/core.py", line 823, in setitem self.set(key, value, retry=True) File "/app/webui/sd-webui-forge/venv/lib/python3.11/site-packages/diskcache/core.py", line 808, in set self._row_insert(db_key, raw, now, columns) File "/app/webui/sd-webui-forge/venv/lib/python3.11/site-packages/diskcache/core.py", line 857, in _row_insert sql( sqlite3.OperationalError: no such column: "size" - should this be a string literal in single-quotes?
2025-05-09 08:57:49,366 - ControlNet - [0;32mINFO[0m - ControlNet UI callback registered. reading metadata for /app/webui/sd-webui-forge/models/Stable-diffusion/v1-5-pruned-emaonly.safetensors: OperationalError Traceback (most recent call last): File "/app/webui/sd-webui-forge/modules/sd_models.py", line 89, in init self.metadata = cache.cached_data_for_file('safetensors-metadata', "checkpoint/" + name, filename, read_metadata) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/app/webui/sd-webui-forge/modules/cache.py", line 119, in cached_data_for_file existing_cache[title] = entry ~~~~~~~~~~~~~~^^^^^^^ File "/app/webui/sd-webui-forge/venv/lib/python3.11/site-packages/diskcache/core.py", line 823, in setitem self.set(key, value, retry=True) File "/app/webui/sd-webui-forge/venv/lib/python3.11/site-packages/diskcache/core.py", line 808, in set self._row_insert(db_key, raw, now, columns) File "/app/webui/sd-webui-forge/venv/lib/python3.11/site-packages/diskcache/core.py", line 857, in _row_insert sql( sqlite3.OperationalError: no such column: "size" - should this be a string literal in single-quotes?
reading metadata for /app/webui/sd-webui-forge/models/Stable-diffusion/麦橘超然majicFlus_v1.safetensors: OperationalError Traceback (most recent call last): File "/app/webui/sd-webui-forge/modules/sd_models.py", line 89, in init self.metadata = cache.cached_data_for_file('safetensors-metadata', "checkpoint/" + name, filename, read_metadata) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/app/webui/sd-webui-forge/modules/cache.py", line 119, in cached_data_for_file existing_cache[title] = entry ~~~~~~~~~~~~~~^^^^^^^ File "/app/webui/sd-webui-forge/venv/lib/python3.11/site-packages/diskcache/core.py", line 823, in setitem self.set(key, value, retry=True) File "/app/webui/sd-webui-forge/venv/lib/python3.11/site-packages/diskcache/core.py", line 808, in set self._row_insert(db_key, raw, now, columns) File "/app/webui/sd-webui-forge/venv/lib/python3.11/site-packages/diskcache/core.py", line 857, in _row_insert sql( sqlite3.OperationalError: no such column: "size" - should this be a string literal in single-quotes?
Exception in thread Thread-3 (preload_extensions_git_metadata): Traceback (most recent call last): File "/opt/conda/lib/python3.11/threading.py", line 1045, in _bootstrap_inner self.run() File "/opt/conda/lib/python3.11/threading.py", line 982, in run self._target(*self._args, **self._kwargs) File "/app/webui/sd-webui-forge/modules/ui_extensions.py", line 541, in preload_extensions_git_metadata extension.read_info_from_repo() File "/app/webui/sd-webui-forge/modules/extensions.py", line 156, in read_info_from_repo d = cache.cached_data_for_file('extensions-git', self.name, os.path.join(self.path, ".git"), read_from_repo) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/app/webui/sd-webui-forge/modules/cache.py", line 119, in cached_data_for_file existing_cache[title] = entry ~~Model selected: {'checkpoint_info': {'filename': '/app/webui/sd-webui-forge/models/Stable-diffusion/v1-5-pruned.ckpt', 'hash': 'a9263745'}, 'additional_modules': ['/app/webui/sd-webui-forge/models/VAE/flux-ae.safetensors', '/app/webui/sd-webui-forge/models/text_encoder/clip_l.safetensors', '/app/webui/sd-webui-forge/models/text_encoder/t5xxl_fp16.safetensors'], 'unet_storage_dtype': None} Using online LoRAs in FP16: False
File "/app/webui/sd-webui-forge/venv/lib/python3.11/site-packages/diskcache/core.py", line 823, in __setitem__
self.set(key, value, retry=True)
File "/app/webui/sd-webui-forge/venv/lib/python3.11/site-packages/diskcache/core.py", line 808, in set
self._row_insert(db_key, raw, now, columns)
File "/app/webui/sd-webui-forge/venv/lib/python3.11/site-packages/diskcache/core.py", line 857, in _row_insert
sql(
sqlite3.OperationalError: no such column: "size" - should this be a string literal in single-quotes?
Running on local URL: http://0.0.0.0:7860
To create a public link, set `share=True` in `launch()`.
[92mIIB Database file has been successfully backed up to the backup folder.[0m
Startup time: 189.4s (prepare environment: 42.7s, launcher: 1.8s, import torch: 86.8s, initialize shared: 1.1s, other imports: 2.6s, setup gfpgan: 0.2s, list SD models: 2.4s, load scripts: 31.1s, create ui: 7.6s, gradio launch: 9.7s, add APIs: 2.6s, app_started_callback: 0.3s).
How do I fix it and solve it, because I need to upgrade to a new dependency to be compatible