8.4 KiB
INSTALL_NOTES
实战安装记录(脱敏)。环境:Ubuntu 22.04 + 双 RTX 3090 + CUDA 12.6 +
Python 3.13 + torch 2.11.0+cu126,ComfyUI 装在 /mnt/modelall/ComfyUI/,
uv 管理 venv。
这份文档按"从零到第一张图"的实际顺序写,包含每一步可能踩到的坑。如果在 别的机器上装,把
/mnt/modelall替换成你的路径即可。
1. 安装 AgeShift 节点包
cd /mnt/modelall/ComfyUI/custom_nodes
git clone https://github.com/aadebuger/ComfyUI-AgeShift.git
cd ComfyUI-AgeShift
source /mnt/modelall/ComfyUI/.venv/bin/activate
export HF_HOME=/mnt/modelall/hf_cache # 关键 — 主盘只有 10GB
uv pip install -r requirements.txt
依赖很轻(transformers / pillow / numpy),几乎一定已经在 ComfyUI venv 里了。
2. 安装 ComfyUI-PuLID-Flux
cd /mnt/modelall/ComfyUI/custom_nodes
git clone https://github.com/balazik/ComfyUI-PuLID-Flux.git
cd ComfyUI-PuLID-Flux
uv pip install -r requirements.txt --no-cache-dir
主要拉:facexlib / onnxruntime-gpu / insightface / timm / ftfy。
⚠️ 容易踩的坑
坑 1:onnxruntime-gpu 版本
CUDA 12.6 需要 onnxruntime-gpu >= 1.18。装完确认:
uv pip show onnxruntime-gpu | grep -i version
坑 2:insightface 编译失败
# 如果报 Cython 缺失
uv pip install cython
uv pip install insightface --no-build-isolation
3. 下载模型权重
Flux 主模型(选一个)
| 选项 | 文件 | 大小 | 备注 |
|---|---|---|---|
| dev fp8(推荐) | flux1-dev-fp8.safetensors |
~12 GB | 无 license,质量好 |
| dev 全精度 | flux1-dev.safetensors |
~23 GB | gated,需 HF token |
| schnell | flux1-schnell.safetensors |
~24 GB | 开放,4 步快,PuLID 效果一般 |
# 方案 A: dev fp8(最推荐)
cd /mnt/modelall/ComfyUI/models/unet
wget "https://huggingface.co/Kijai/flux-fp8/resolve/main/flux1-dev-fp8.safetensors"
# 方案 B: dev 全精度
huggingface-cli login # 粘贴 HF token,需要先在网页同意 license
huggingface-cli download black-forest-labs/FLUX.1-dev flux1-dev.safetensors \
--local-dir /mnt/modelall/ComfyUI/models/unet/
Flux 配套(CLIP + VAE)
# 如果还没装 Flux 配套权重
cd /mnt/modelall/ComfyUI/models
huggingface-cli download MaxedOut/ComfyUI-Starter-Packs Flux1/clip/clip_l.safetensors \
--local-dir hf_cache/manual/
# 类似下载 t5xxl_fp8_scaled.safetensors, ae.safetensors,然后 symlink 进 models/clip/ models/vae/
# 实际项目里 Hua 的环境已经有,通过 symlink 指向 MaxedOut starter pack:
ls -lh /mnt/modelall/ComfyUI/models/clip/
# clip_l.safetensors -> /mnt/modelall/hf_cache/.../Flux1/clip/clip_l.safetensors
# t5xxl_fp8_scaled.safetensors -> ...
PuLID-Flux 权重(~1.1 GB)
mkdir -p /mnt/modelall/ComfyUI/models/pulid
cd /mnt/modelall/ComfyUI/models/pulid
wget "https://huggingface.co/guozinan/PuLID/resolve/main/pulid_flux_v0.9.1.safetensors"
⚠️ InsightFace antelopev2(关键步骤,容易漏)
PuLID-Flux 用 antelopev2 不是默认的 buffalo_l,不会自动下载。
必须手动放,而且目录结构要正确(双层 models,反直觉但 InsightFace 库
就是这么要求的):
cd /mnt/modelall/ComfyUI/models/insightface
mkdir -p models && cd models
# 从 GitHub releases
wget "https://github.com/deepinsight/insightface/releases/download/v0.7/antelopev2.zip"
unzip antelopev2.zip && rm antelopev2.zip
# 验证目录结构
ls -lh antelopev2/
# 必须有 5 个文件:
# 1k3d68.onnx 2d106det.onnx genderage.onnx glintr100.onnx scrfd_10g_bnkps.onnx
最终路径必须是:/mnt/modelall/ComfyUI/models/insightface/models/antelopev2/
(注意两层 models。少一层会触发 AssertionError: assert 'detection' in self.models。)
如果 GitHub releases 拉不动:
# 方案 1: HF 镜像
huggingface-cli download MonsterMMORPG/tools antelopev2.zip --local-dir /tmp/
unzip /tmp/antelopev2.zip -d /mnt/modelall/ComfyUI/models/insightface/models/
# 方案 2: 走 GitHub 代理
wget "https://ghproxy.com/https://github.com/deepinsight/insightface/releases/download/v0.7/antelopev2.zip"
EVA02-CLIP-L(自动下载,不用管)
PuLID-Flux 节点首次运行时自动从 HF 拉 EVA02_CLIP_L_336_psz14_s6B.pt(~430 MB)
到 $HF_HOME。第一张图会卡 1-2 分钟,之后从 cache 走。
Age 检测器(自动下载,不用管)
nateraw/vit-age-classifier(~330 MB)首次运行从 HF 拉到 $HF_HOME。
4. 启动 ComfyUI(模板)
pkill -9 -f main.py; sleep 3
cd /mnt/modelall/ComfyUI && source .venv/bin/activate
export HF_HOME=/mnt/modelall/hf_cache # 关键!别忘
nohup python main.py --listen 0.0.0.0 --port 8188 > ~/comfy_start.log 2>&1 &
sleep 35
grep -iE "IMPORT FAILED|pulid|AgeShift|error" ~/comfy_start.log | head -20
预期:看到 PuLID-Flux 和 AgeShift 都被加载,没有 IMPORT FAILED。
5. 验证所有节点都注册了
curl -s http://127.0.0.1:8188/object_info | python3 -c "
import json,sys
d = json.load(sys.stdin)
need = ['AgeDetectorLoader','AgeDetect','AgePromptBuilder','AgeRangeBatch',
'PulidFluxModelLoader','PulidFluxEvaClipLoader',
'PulidFluxInsightFaceLoader','ApplyPulidFlux']
for n in need:
print(f' {n}:', '✓' if n in d else '✗')
print(f' total: {len(d)}')"
8 个都打 ✓ 才能跑完整 pipeline。
6. 客户端 CLI
CLI 自带 PEP 723 inline metadata,uv 会自动管依赖。不用 pip install 任何东西:
# Mac 本地
cd /path/to/ComfyUI-AgeShift
# 单图检测(~2 秒)
uv run --script cli/age_shift_cli.py face.jpg --detect-only --ip 10.8.0.12
# 完整流程
uv run --script cli/age_shift_cli.py face.jpg \
--target-ages 5,15,25,45,65 \
--gender male --subject man \
--flux-unet flux1-dev-fp8.safetensors \
--flux-t5 t5xxl_fp8_scaled.safetensors \
--pulid-weight 0.95 --guidance 3.0 --steps 28 --seed 42 \
--ip 10.8.0.12 --out ./out
--flux-t5 t5xxl_fp8_scaled.safetensors 是因为 MaxedOut Starter Pack 给的是
scaled 版,默认 CLI 里写的是 e4m3fn。其他 Flux 文件名也类似,以你服务器
ls models/unet/ 实际看到的为准。
7. 历史踩过的坑汇总
| 坑 | 表现 | 解决 |
|---|---|---|
| 主盘 HF cache 撑满 | 模型下到一半失败 | 必须 export HF_HOME=/mnt/modelall/hf_cache |
processor 类名不一致 |
ImportError: cannot import name 'ViTImageProcessor' |
节点里改用 AutoImageProcessor(已修) |
| CPU 上跑 fp16 | NaN 或 warn | loader 强制 CPU=fp32(已修) |
image tensor 是 fp16 |
(... * 255).astype(uint8) 越界 |
detect 里 .float() 兜底(已修) |
websocket 包名错装 |
ModuleNotFoundError: websocket |
装的是 websocket-client,不是 websocket |
| PuLID 节点目录在但不注册 | curl object_info 看不到 | 多半是 facexlib/onnxruntime-gpu 缺,装 requirements |
assert 'detection' in self.models |
InsightFace 启动失败 | antelopev2 路径错(必须双层 models)或文件不全(5 个 onnx 缺一不可) |
| 生成的脸不像源图 | 身份漂移 | 见 README 的 identity preservation tuning 章节 |
| 5 岁生成出"小型成人" | child 方向用了 adult 默认参数 | child 方向降 --pulid-weight 0.75 |
8. CLI 自检 checklist(给新机器用)
SERVER=10.8.0.12:8188
# 0. 服务器在跑
curl -s -o /dev/null -w "HTTP %{http_code}\n" http://$SERVER/
# 1. 节点都注册了
curl -s http://$SERVER/object_info | python3 -c "
import json, sys
d = json.load(sys.stdin)
for n in ['AgeDetectorLoader','AgeDetect','AgePromptBuilder','AgeRangeBatch',
'PulidFluxModelLoader','ApplyPulidFlux']:
print(f' {n}: {\"✓\" if n in d else \"✗\"}')"
# 2. 模型文件齐
for f in models/unet/flux1-dev-fp8.safetensors \
models/clip/clip_l.safetensors \
models/clip/t5xxl_fp8_scaled.safetensors \
models/vae/ae.safetensors \
models/pulid/pulid_flux_v0.9.1.safetensors \
models/insightface/models/antelopev2/scrfd_10g_bnkps.onnx; do
if [ -e "/mnt/modelall/ComfyUI/$f" ]; then echo " ✓ $f"; else echo " ✗ $f MISSING"; fi
done
# 3. 端到端检测
uv run --script cli/age_shift_cli.py test.jpg --detect-only --ip $SERVER
预期最终输出:
[1/3] Uploading test.jpg → 10.8.0.12:8188 ...
uploaded as: test.jpg
[2/3] Detecting age ...
prompt_id=...
→ Estimated age: 34 (adult) | top bin: 30-39 (0.62) | top-3: 30-39=0.62, ...
Done (detect only).