ACCC1380's picture
download
raw
7.1 kB
#!/usr/bin/env bash
# 将 Modal 镜像内的安装步骤转换为 Bash;在 Debian/Ubuntu 容器或主机中以 root 运行。
# 需预装 Python 3.12 及其 pip(对应原来的 python_version="3.12")。
# 本脚本配置当前环境,不会自行创建或发布容器镜像。
set -Eeuo pipefail
if [[ "$EUID" -ne 0 ]]; then
echo '请以 root 身份运行:bash build_sdwebui_bash.sh' >&2
exit 1
fi
PYTHON_BIN="${PYTHON_BIN:-python3.12}"
if ! command -v "$PYTHON_BIN" >/dev/null 2>&1; then
echo "未找到 $PYTHON_BIN,请先安装 Python 3.12 和 pip。" >&2
exit 1
fi
"$PYTHON_BIN" -c 'import sys; assert sys.version_info[:2] == (3, 12), "需要 Python 3.12"'
"$PYTHON_BIN" -m pip --version
if [[ -z "${HF_TOKEN:-}" ]]; then
read -r -s -p '请输入可访问 ACCC1380/private-model 的 HF_TOKEN:' HF_TOKEN
printf '\n'
fi
: "${HF_TOKEN:?HF_TOKEN 不能为空}"
export HF_TOKEN
export DEBIAN_FRONTEND=noninteractive
# 基础工具及常用网络工具
apt-get update
apt-get install -y --no-install-recommends \
ca-certificates aria2 sshpass openssh-client unzip git \
procps curl wget sudo gnupg psmisc p7zip-full \
iputils-ping iproute2 dnsutils traceroute net-tools
# PyTorch CUDA 13.0 环境
"$PYTHON_BIN" -m pip install torch torchvision torchaudio \
--index-url https://download.pytorch.org/whl/cu130
# 保留原来的依赖和版本
"$PYTHON_BIN" -m pip install \
jupyterlab \
'GitPython==3.1.46' \
'Pillow==12.2.0' \
'accelerate==1.13.0' \
'audioop-lts==0.2.2; python_version >= "3.13"' \
'av==17.0.0' \
'comfy-kitchen==0.2.10' \
'diffusers==0.37.1' \
'diskcache==5.6.3' \
'einops==0.8.2' \
'facexlib==0.3.0' \
'fastapi==0.127.1' \
'httpx==0.24.1' \
'huggingface-hub==0.36.2' \
'inflection==0.5.1' \
'joblib==1.5.3' \
'kornia==0.6.12' \
'lark==1.2.2' \
'numpy==2.3.5' \
'omegaconf==2.2.3' \
'opencv-python==4.10.0.84' \
'peft==0.17.1' \
'piexif==1.1.3' \
'pillow-heif==1.3.0' \
'pillow-jxl-plugin==1.3.7' \
'protobuf==4.25.9' \
'psutil==6.1.1' \
'pydantic-core==2.27.2' \
'pydantic==2.10.6' \
'pyyaml==6.0.3' \
'rich==14.3.3' \
'safetensors==0.7.0' \
'scikit-image==0.25.2' \
'setuptools==69.5.1' \
'spandrel-extra-arches==0.2.0' \
'spandrel==0.4.2' \
'torchdiffeq==0.2.5' \
'torchsde==0.2.6' \
'tqdm==4.67.3' \
'transformers==4.56.2' \
modelscope
# 原片段未提供 sdwebui_hf_download_command 的实现,改用 curl 下载。
# 支持 .part 断点续传;每 5 秒读取实际文件大小,成功后改为目标文件名。
sdwebui_hf_download_command() (
set -Eeuo pipefail
repo_id="$1"
remote_file="$2"
local_dir="$3"
target_file="$4"
part_file="${target_file}.part"
mkdir -p "$local_dir" "$(dirname "$target_file")"
download_pid=''
monitor_pid=''
cleanup() {
if [[ -n "$monitor_pid" ]]; then
kill "$monitor_pid" 2>/dev/null || true
wait "$monitor_pid" 2>/dev/null || true
fi
if [[ -n "$download_pid" ]]; then
kill "$download_pid" 2>/dev/null || true
wait "$download_pid" 2>/dev/null || true
fi
}
trap cleanup EXIT
trap 'exit 130' INT
trap 'exit 143' TERM
printf '\n开始下载:%s/%s\n' "$repo_id" "$remote_file"
curl --fail --location --silent --show-error \
--retry 5 --retry-delay 5 --connect-timeout 30 \
--continue-at - \
--header @<(printf 'Authorization: Bearer %s\n' "$HF_TOKEN") \
--output "$part_file" \
"https://huggingface.co/${repo_id}/resolve/main/${remote_file}" &
download_pid=$!
(
previous_size=$(stat -c '%s' "$part_file" 2>/dev/null || printf '0')
previous_time=$(date +%s)
while kill -0 "$download_pid" 2>/dev/null; do
sleep 5
current_size=$(stat -c '%s' "$part_file" 2>/dev/null || printf '0')
current_time=$(date +%s)
awk -v name="${target_file##*/}" \
-v size="$current_size" -v previous="$previous_size" \
-v elapsed="$((current_time - previous_time))" \
'BEGIN {
if (elapsed < 1) elapsed = 1;
speed = (size - previous) / elapsed / 1048576;
if (speed < 0) speed = 0;
printf "[%s] 已落盘 %.2f MiB,速度 %.2f MiB/s\n", name, size / 1048576, speed;
}'
previous_size="$current_size"
previous_time="$current_time"
done
) &
monitor_pid=$!
if wait "$download_pid"; then
download_pid=''
else
status=$?
download_pid=''
printf '下载失败(退出码 %s):%s;保留 .part 供重试。\n' "$status" "$remote_file" >&2
exit "$status"
fi
kill "$monitor_pid" 2>/dev/null || true
wait "$monitor_pid" 2>/dev/null || true
monitor_pid=''
test -s "$part_file"
mv -f "$part_file" "$target_file"
printf '下载完成:%s(%s 字节)\n' "$target_file" "$(stat -c '%s' "$target_file")"
)
df -h
curl --fail --location https://ipinfo.io
printf '\n'
mkdir -p ~/.ssh
chmod 700 ~/.ssh
if ! grep -qxF 'StrictHostKeyChecking no' ~/.ssh/config 2>/dev/null; then
echo 'StrictHostKeyChecking no' >> ~/.ssh/config
fi
chmod 600 ~/.ssh/config
# LoRA
sdwebui_hf_download_command \
'ACCC1380/private-model' \
'upload/betanon_lora_000004000.safetensors' \
'/root/sd-webui-forge-neo/models/Lora' \
'/root/sd-webui-forge-neo/models/Lora/betanon_lora_000004000.safetensors'
# sd-neo.tar:保持原来的本地文件名和解压位置
sdwebui_hf_download_command \
'ACCC1380/private-model' \
'upload/sd-neo.tar' \
'/root' \
'/root/sd-webui-forge-neo.tar'
tar xvf /root/sd-webui-forge-neo.tar -C /
test -d /root/sd-webui-forge-neo
# 大模型
sdwebui_hf_download_command \
'ACCC1380/private-model' \
'upload/BSSANIRLANIMASemi_v20.safetensors' \
'/root/sd-webui-forge-neo/models/Stable-diffusion' \
'/root/sd-webui-forge-neo/models/Stable-diffusion/BSSANIRLANIMASemi_v20.safetensors'
df -h
ls /root
# 使用所选 Python 对应的 ModelScope 命令
PYTHON_SCRIPTS_DIR=$("$PYTHON_BIN" -c 'import sysconfig; print(sysconfig.get_path("scripts"))')
"$PYTHON_SCRIPTS_DIR/modelscope" download \
--model ACCC1380/Anima_in_real_update_v2_epoch_20_20260908_083702 \
--local_dir /root/sd-webui-forge-neo/models/Lora
# 检验压缩包,成功解密还原缩略图后再删除压缩包
7z t -pNeko1102202 \
/root/sd-webui-forge-neo/models/Lora/lora_thumbnails_encrypted.zip
7z x -y -pNeko1102202 \
/root/sd-webui-forge-neo/models/Lora/lora_thumbnails_encrypted.zip \
-o/root/sd-webui-forge-neo/models/Lora
rm -f /root/sd-webui-forge-neo/models/Lora/lora_thumbnails_encrypted.zip
# 最终检查两个目标目录
df -h
ls -lh /root/sd-webui-forge-neo/models/Lora
ls -lh /root/sd-webui-forge-neo/models/Stable-diffusion
printf '\nSD WebUI 环境配置完成。\n'

Xet Storage Details

Size:
7.1 kB
·
Xet hash:
79c5124d31c637537f2e2c628b5914ae92aa23edf42901653183ea4bc88ed112

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.