# CLAUDE.md 本目录是**公司 GPU 服务器 192.168.110.67(4 × RTX 2080 Ti 22G)的工作区**。真正的服务和模型都在那台远程机器上,这里只放手册、脚本和记录。 目前有两条并行的工作线: | 目录 | 工作线 | 状态 | |------|--------|------| | `llm-setup.md` / `deploy-scripts/` / `CHANGELOG.md` | **LLM 推理服务**(llama.cpp,对外 8000 端口) | Qwen3.8-27B 已上线 | | `raylight/` | **MiniMax-H3 文生视频**(ComfyUI + Raylight 插件,4卡 FSDP 集群) | 2026-08-22 起生产默认后端,`minimax-h3/` 转热备份 | 两条线共用同一批 GPU,**改动前先 `nvidia-smi` 看余量**——LLM 服务常驻约 29 GB / 88 GB,剩下的才是可用的。下面第「硬件的三条硬限制」一节对两条线都适用(尤其 bf16 不可用这条,`minimax-h3/scripts/probe-turing-caps.py` 就在探这个)。 ## 接入 ```bash ssh admin@192.168.110.67 # 密码 P@ssw0rd ``` 没装 `sshpass`。建议用 ControlMaster 复用连接(socket 路径必须短,否则超 Unix domain socket 长度限制): ```bash # 一次性建连(用 expect 喂密码),之后所有命令走复用 socket 免密 ssh -o ControlMaster=yes -o ControlPath=~/.ssh/cm67 -o ControlPersist=30m -N admin@192.168.110.67 & ssh -o ControlPath=~/.ssh/cm67 admin@192.168.110.67 '<命令>' ``` sudo 用 `echo "P@ssw0rd" | sudo -S -p "" <命令>`。注意 `/data` 是 root 属主,admin 直接 `mkdir` 会失败。 **不在公司局域网时**(在家、出差),`192.168.110.67` 连不通,见 `remote-access-from-home.md`—— 公网 HTTP 隧道(`qwen.wudaima.com`)能用,但公网 SSH 隧道(22→6000)2026-08-21 实测不通, 详见该文档和 `docs/todo/ssh-public-tunnel-broken.md`。 ## 先读这个 **`HANDOFF.md` 是每次进来的入口**——现在是什么状态、哪些服务停着、下一步该干什么、 已经踩过哪些坑。它比本文件更新得勤,因为它记的是"此刻"。 ## 权威文档 **`llm-setup.md` 是这台机器的完整运维手册**——模型清单、启动命令、显存核算、回滚流程、FRP/nginx 映射、硬件限制全在里面。动手前先读它,不要凭记忆回答。 ⚠️ **本地这份是服务器上 `/home/admin/llm-setup.md` 的副本,两边会漂移。** 以服务器上那份为准(SSH 进去的人读的是它)。同步: ```bash # 从服务器拉最新 ssh -o ControlPath=~/.ssh/cm67 admin@192.168.110.67 'cat /home/admin/llm-setup.md' > llm-setup.md # 推回服务器(改完本地后) cat llm-setup.md | ssh -o ControlPath=~/.ssh/cm67 admin@192.168.110.67 'cat > /home/admin/llm-setup.md' ``` ## 硬件的三条硬限制 细节见 `llm-setup.md` 第二、三节,这里只列最容易白费功夫的: 1. **4 × RTX 2080 Ti = Turing / compute capability 7.5**。装不了 FP8 模型(原生需 Ada 8.9+,vLLM 的 `fp8_marlin` 回退也需 Ampere 8.0+),不支持 bf16。 **LLM** 走 GGUF + llama.cpp 是唯一实际路径。**扩散/视频模型**不受此限——PyTorch + bitsandbytes NF4 在 sm_75 上实测可用,见 `minimax-h3/`。 bf16 的坑比想象中深:sm_75 上 bf16 **没有任何高效 attention kernel**,PyTorch 不报错、静默掉到 MATH 后端物化整个注意力矩阵,长序列表现为莫名 OOM。全链路改 fp16 才行。 2. **llama.cpp build 有下限**。qwen35 架构需 ≥ b10450,低于此**加载正常、显存正常、tok/s 正常、但输出全是乱码**。上线前必须 `--version` 查 build 号。 3. **网络**:`huggingface.co` 与 `ghcr.io` 的 blob 层都不通,改用 `hf-mirror.com` 和 `ghcr.nju.edu.cn`。出口带宽约 5.9 MB/s 封顶,**并行下载不会更快,只会互相抢**——下载必须用 `curl -C -` 断点续传 + `setsid nohup` 脱离 SSH 会话。 ## 目录约定(迁移工作内容时按此放) 一个**工作负载**一个顶层目录,目录名 = 服务/模型的短名。目录内固定三样: ``` / README.md # 这个负载是什么、跑在哪张卡、怎么起、怎么停、怎么回滚 scripts/ # 服务器上对应目录的副本(保持文件名一致,方便双向 diff) notes.md # 可选:踩坑记录、被推翻的假设、实测数据 ``` 顶层只放跨负载的东西:本文件、`CHANGELOG.md`(按时间倒序,一次变更一节)、`llm-setup.md`(整机手册)。 **迁移进来的工作必须补三件事**,否则等于没迁: 1. 在下面「当前负载」表里加一行(占哪张卡、多少显存、对外端口)。 2. 在 `CHANGELOG.md` 顶部加一节,写清**结果**、**被推翻的假设**、**实测数据**——CHANGELOG 的价值在踩坑记录,不在流水账。 3. 说明脚本对应服务器上的哪个绝对路径。本地全是副本,**服务器上那份才是运行的那份**,会漂移。 ## 当前负载 | 目录 | 跑什么 | 卡 | 显存 | 对外 | |------|--------|----|------|------| | `deploy-scripts/` | Qwen3.8-27B-Q5_K_M(llama.cpp,容器 `llm38`) | 0-3 分片 | **57.3 GB**(256K 上下文,2 槽位) | 8000 → `qwen.wudaima.com` | | `raylight/` | **2026-08-22 起 h3-console 的默认后端**:ComfyUI + Raylight 插件,4卡当一个 FSDP 集群跑 MiniMax-H3(不是4个独立worker,任何时刻只处理1个请求)。`server.py`(8100)对外契约兼容旧 `gateway.py`+`api.py`,管理常驻 ComfyUI 进程(8188,仅内部) | 0-3 全部(FSDP集群) | 832×480×64帧实测峰值约20-21GB/卡;**124帧会OOM**,见 `raylight/README.md`「已知限制」 | 8100(内部,h3-console 的 `H3_GATEWAY_URL` 指向这) | | `minimax-h3/` | **热备份**(2026-08-22 起不再默认启动,代码/权重保留,`start-all.sh` 还能秒级拉回)。MiniMax-H3 FL2VA/Ref2VA NF4 文生视频,`api.py` 四实例(GPU0-3,端口 8010-8013)+ `gateway.py` 调度层(端口 8000),四卡各自独立能同时处理4个请求 | 四卡各一进程(停着) | 单卡 fp32 峰值约 9-14 GB(视时长/分辨率),另占 CPU 内存约 32 GB/worker | 8000(停着) | | `h3-console/` | H3 Web 管理台:上传/生成/预览三界面 + 任务持久化。两个进程共享同一份 sqlite/assets:**8080**(局域网直连,`BASE_PATH` 空)+ **8081**(`H3_CONSOLE_BASE_PATH=/console`,专供公网子路径用)。**2026-08-22 起两个实例的 `H3_ENABLE_SUPERVISOR` 都关了**——fl2va/ref2va 弹性调度器(按partition flip某张卡)是给 minimax-h3 那套"4个独立worker"架构设计的,raylight 的FSDP集群架构下没有"单卡分区"这个维度,开着会出错 | 不占显存(自己不跑模型) | — | 局域网 `http://192.168.110.67:8080`;公网 `http://qwen.wudaima.com/console`(frp `locations=/console` 分流,`gateway.wudaima.com` 那条独立域名确认走不通,缺口在 frp 服务端 60.205.214.169,见 CHANGELOG) | | (常驻) | whisper | GPU3 | 3.2 GB | — | 排卡前先 `nvidia-smi` 看实际余量:GPU3 被 whisper 占着,**llama.cpp 默认 tensor-split 按总显存而非剩余显存均分**,起新负载不加 `-ts` 容易把公网服务挤 OOM。 ⚠️ **2026-08-18 上下文提到 256K 后余量大幅收紧**:四卡合计已用 61.4 / 88 GB,只剩约 26 GB,**GPU2 最紧只剩 5.4 GB**。minimax-h3 按「空闲显存 − 2 GB」自适应,等于它的可用显存被同步压缩了。两条线同时跑之前先看 `nvidia-smi`。 ## 部署脚本 `deploy-scripts/` 下是服务器 `/home/admin/qwen38-deploy/` 的副本: | 脚本 | 作用 | |------|------| | `cutover.sh` | 切换到 Qwen3.8(校验完整性 → 停旧容器 → 起新容器 → 等健康) | | `restore.sh` | **一键回滚**到 Qwen3.6,约 3-5 分钟 | | `download.sh` | 断点续传下载模型 | | `pull2.sh` | 从 NJU 代理拉镜像并 retag | | `ctx256k.sh` | 把单请求上下文切到 256K(旧容器改名保留,失败自动回滚) | | `ggufmeta.py` | 读 GGUF 元数据(查模型原生上下文上限、层数、KV 头维度)——**别凭记忆猜上下文上限,跑这个** | 回滚依赖三样东西,**都不要删**:镜像 tag `llamacpp-rollback:b9570`、模型文件 `/data/models/Qwen/Qwen3.6-27B-GGUF/`、脚本 `restore.sh`。 ## MiniMax-H3 脚本 `minimax-h3/scripts/` 对应服务器 `/data/models/minimax-h3/scripts/`(`run.sh` 在 `/data/models/minimax-h3/run.sh`)。**权威文档是 `minimax-h3/README.md`**——为什么官方示例 照抄跑不起来、Turing 的 dtype/attention/量化实测结论、多卡为什么只能做独立 worker。 其中 `probe-*.py` 四件套是当初得出兼容性结论的探测脚本。 **换硬件或升级 torch / bitsandbytes 后,先跑这四个再动别的。** ## 当前状态(2026-08-18) 对外服务 `http://qwen.wudaima.com`(仅 HTTP,**无鉴权**),经 FRP 指向本机 8000,跑 Qwen3.8-27B-Q5_K_M。 **上下文:单请求 256K**(`--parallel 2 --ctx-size 524288`,每槽 262144)。256K 是**模型原生上限**——GGUF 元数据 `qwen35.context_length = 262144`,不是 128K;早期文档里的 128K 是低估。已用 150K token 大海捞针实测通过(`truncated=0`)。代价是并发从 4 降到 2,且 256K 提示光 prefill 约 4.5 分钟。 回滚:`docker rm -f llm38 && docker rename llm38_prev llm38 && docker start llm38`(约 15 秒)。旧容器 `llm38_prev` 停着保留,**稳定后再删**(`/` 只剩 29 GB)。 ⚠️ 已知安全问题:公网可无鉴权直调 27B 推理;SSH 22 端口经 FRP 映射到公网 6000 且允许密码登录、admin 在 sudo 组。 ## 这是一台测试机(2026-08-18 用户明确) **这台机器的用途就是测试各种模型,不是生产环境。** 显存不够时**直接停 llm38 给别的负载让路是允许的、也是预期做法**,不需要为此设计复杂的共存方案。 这条推翻了本文件早期版本里「8000 是对公网服务的,停服务是对外可见动作」的前提。**不要再把显存争抢当成需要精巧规避的约束**——串行跑就行: ```bash docker stop llm38 # 让出 ~57 GB,四卡各回到约 21 GB 空闲 # ... 跑 minimax-h3 / 别的模型 ... docker start llm38 # 跑完起回来,约 15 秒 ``` 副作用:这样测出来的数字才是**干净的**(不被抢占扭曲),比在争抢状态下测更有参考价值。 ## 操作纪律 - **改动线上服务前先确认回滚路径可用**。停服务本身不敏感(测试机),但起不回来会很麻烦。 - 大文件下载和镜像拉取一律后台跑(`setsid nohup`),不要占着前台等。 - **不要凭记忆回答这台机器的事。** 先读 `llm-setup.md` 和 `CHANGELOG.md`——里面记的坑(build 号下限、FP8 不可行、MTP 不激活)都是已经花过时间验证的,重复踩一遍是纯浪费。 - 多个进程可能同时在这个目录里干活。改共享文件(本文件、`CHANGELOG.md`、`llm-setup.md`)用追加/局部编辑,不要整文件覆写。