# 本地大模型服务配置总览 > 最后更新:2026-08-18 > 机器角色:本地 GPU 服务器,运行 Qwen/DeepSeek 大模型,通过 FRP 反向代理对外提供服务 > 硬件:4 × RTX 2080 Ti 22G(**Turing / compute capability 7.5**)· 125G 内存 · Ubuntu 22.04 · 驱动 570.153.02 / CUDA 12.8 --- ## 〇、当前运行状态(2026-08-18) | 服务 | 端口 | 容器/进程 | 模型 | |------|------|-----------|------| | **大模型 API** | 8000 | 容器 `llm38` | **Qwen3.8-27B-Q5_K_M**(llama.cpp b10481) | | 语音转写 | 8002 | 容器 `whisper` | whisper-server | | 文本嵌入 | 7590 | gunicorn (PID 1616) | M3E-base | | 文生图 | 7860(仅本机) | venv (PID 1919) | SD WebUI Forge | **实测指标**:生成 23.4 tok/s(150K 上下文时 16.7)· 显存 **57.3 GB / 88 GB**(四卡)· **单请求上下文 262144(256K)** > 容器名从 `llm` 改成了 `llm38`。旧的 `llm` 容器保留为 `Exited (0)` 状态作回滚锚点,**不要删**。 --- ## 一、整体架构 ``` 外部用户 | v qwen.wudaima.com (FRP 公网域名,无鉴权 ⚠) | v FRP 服务端 60.205.214.169:7009 | v 本机 127.0.0.1:8000 | +-- [当前] llama.cpp b10481 (容器 llm38) | +-- Qwen3.8-27B-Q5_K_M.gguf | +-- [历史] llama.cpp b9570 (容器 llm) <- 回滚用,已停 | +-- Qwen3.6-27B-IQ4_XS.gguf | +-- [历史] vLLM 引擎 (compose.72b/32b.yaml) +-- Qwen2.5-72B-Instruct-GPTQ-Int4 +-- DeepSeek-R1-Distill-Qwen-32B-AWQ ``` **注意**:8000 端口同一时间只能跑一个模型服务。 --- ## 二、★ 这台机器的硬件约束(2080 Ti = Turing SM 7.5)★ > 这一节是 2026-08-18 部署 Qwen3.8 时踩出来的,**新增模型前必读**,能省掉大量试错。 ### 2.1 绝对做不了的事 | 事项 | 原因 | |------|------| | **跑 FP8 量化模型** | FP8 原生需要 Ada(8.9)/Hopper(9.0);vLLM 的 `fp8_marlin` 回退内核也要求 Ampere(8.0+)。SM 7.5 两条路都够不着,无法绕过 | | **用 bf16** | Turing 不支持。现有 vLLM compose 全都写 `--dtype=half` 就是这个原因 | | **用 `server-cuda13` 镜像** | CUDA 13 运行时要求驱动 580+,本机是 570.153.02,会报 `forward compatibility was attempted on non supported HW` | | **MTP 推测解码提速** | `--spec-type draft-mtp` 在 sm_75 上对 hybrid(SSM+attention) 模型不激活(llama.cpp issue #24670)。网上「+33~39% 速度」的说法在本机吃不到 | | **1M 上下文** | 需约 92.8 GB,超过物理 85.9 GB。**注意 262144 是 `n_ctx_train`,超过它才需要 YaRN 外插**——`--ctx-size 524288 --parallel 2` 是每槽 262144,属原生范围,不涉及 YaRN(旧版本此行写「524288 (YaRN 2x)」,把总池和单请求上限混淆了,已订正) | ### 2.2 能做但有坑 | 事项 | 说明 | |------|------| | **llama.cpp build 下限** | 跑 Qwen3.8/qwen35 架构**必须 ≥ b10450**(DeltaNet CUDA 修复 commit `ece963f4`)。b10419~b10450 的症状是**加载正常、显存正常、tok/s 正常、输出全是乱码** —— 极具迷惑性,务必先查 build 号 | | **CUDA graphs** | PR #25749 给 Volta/Turing 开了 CUDA graphs,但 issue #25835 报告显存逐轮增长直至 OOM。**本机部署已设 `GGML_CUDA_DISABLE_GRAPHS=1` 规避**,上游修复后可 A/B 试着去掉 | | **JIT 编译** | SM 7.5 在官方镜像里只有 PTX 没有 SASS,冷启动要驱动现编 1~2 分钟。已挂 `/data/nvcache38:/root/.nv` 持久化缓存 | | **prefill 偏慢** | GDN chunked kernel 未合入(PR #26001),走逐 token 路径。**不要拿 3090/4090 的 pp 数字做验收标准** | | **KV cache 量化** | Turing 上 cc < Ada 时 `--cache-type-k/v` 会触发额外 f16 转换开销,收益常被吃掉。显存够就保持 f16 | | **`-sm` 切分模式** | 四卡无 P2P(`nvidia-smi topo -p2p r` 全 CNS)且 GPU0/1 与 GPU2/3 跨 NUMA。**必须用 `-sm layer`**,`row`/`tensor` 会走主机内存性能灾难 | | **默认 tensor-split 陷阱** | llama.cpp 按**总显存**而非**剩余显存**均分。GPU0 有 embedding+SD 占约 840 MiB、GPU3 有 whisper 占 3258 MiB,起第二个大模型时必须显式 `-ts` 或 `--device`,否则 GPU3 先 OOM | ### 2.3 能跑 Turing 的证据(供以后怀疑时复查) - `ggml/src/ggml-cuda/CMakeLists.txt` 中 `list(APPEND CMAKE_CUDA_ARCHITECTURES 75-virtual 80-virtual 86-real)` 在所有 CUDA 版本判断**之外**,无条件执行 - `.devops/cuda.Dockerfile` 用 `CUDA_DOCKER_ARCH=default`,即走上面的默认列表 - 容器日志 `ARCHS = 500,610,700,750,800,860,890,900,1200`,750 在内 - Gated DeltaNet 算子 `gated_delta_net.cu` 全文无任何架构判断,纯 fp32 + warp reduce - Flash Attention 的 `ggml_cuda_fattn_mma_get_config_turing()` 前四条就是 `CONFIG_CASE(256,256,...)`,正是 Qwen3.8 的 head_dim=256 --- ## 三、★ 网络约束(下载模型/镜像前必读)★ | 目标 | 状态 | 替代 | |------|------|------| | `huggingface.co` | ❌ 不通(超时) | ✅ `hf-mirror.com` | | `ghcr.io` blob 层 | ❌ 拉取空转重试 | ✅ `ghcr.nju.edu.cn`(南大代理,拉完 `docker tag` 回原名) | | Docker Hub | ✅ 已配镜像加速 | `/etc/docker/daemon.json` 中 registry-mirrors | **出口带宽约 5.9 MB/s 封顶**(实测:换域名并发也突破不了,是本机出口上限而非对端限速)。20GB 模型约需 60 分钟,**并行下载不会更快,只会互相抢**。下载务必用断点续传(`curl -C -`)+ `setsid nohup` 脱离 SSH 会话。 --- ## 四、模型文件位置 所有模型在 `/data/models/`(1.8T 盘,当前用 1.4T): | 模型 | 路径 | 说明 | |------|------|------| | **Qwen3.8-27B-GGUF** | `/data/models/Qwen/Qwen3.8-27B-GGUF/` | **当前在跑**。Q5_K_M 19.32GiB + mmproj-f16 885MB | | Qwen3.6-27B-GGUF | `/data/models/Qwen/Qwen3.6-27B-GGUF/` | 回滚目标,IQ4_XS | | Qwen3-Coder-Next-GGUF | `/data/models/Qwen/Qwen3-Coder-Next-GGUF/` | | | Qwen3-30B-A3B-Instruct-2507 | `/data/models/Qwen/Qwen3-30B-A3B-Instruct-2507/` | | | Qwen2.5-72B-Instruct-GPTQ-Int4 | `/data/models/Qwen/Qwen2.5-72B-Instruct-GPTQ-Int4/` | vLLM 用 | | Qwen-72B-Chat-Int4 / QwQ-32B-Preview | `/data/models/Qwen/` | 旧版 | | DeepSeek-R1-Distill-Qwen-32B(-AWQ) / 14B / 7B | `/data/models/deepseek-ai/`、`/data/models/DeepSeek-R1-Distill-Qwen-32B-AWQ/` | | | GLM-4.7-Flash-GGUF / gpt-oss-120b-GGUF | `/data/models/unsloth/` | 未部署 | | M3E 嵌入模型 | `/home/admin/llm/m3e-base/` | 7590 端口在用 | --- ## 五、★ 当前部署:Qwen3.8-27B ★ **不走 compose,用 `docker run` 脚本管理**,脚本都在 `/home/admin/qwen38-deploy/`: | 脚本 | 作用 | |------|------| | `cutover.sh` | 切换到 Qwen3.8(校验 sha256/字节 → 停 llm → 起 llm38 → 等健康) | | `restore.sh` | **一键回滚到 Qwen3.6**,约 3-5 分钟 | | `download.sh` | 断点续传下载模型(60 次重试) | | `pull2.sh` | 从 NJU 代理拉镜像并 retag | ### 5.1 启动命令 ```bash docker run -d --name llm38 --restart unless-stopped --gpus all \ -p 8000:8000 \ -v /data/models:/jsxc \ -v /data/nvcache38:/root/.nv \ -e GGML_CUDA_DISABLE_GRAPHS=1 \ -e CUDA_CACHE_MAXSIZE=2147483648 \ --health-cmd "curl -fsS http://localhost:8000/health || exit 1" \ --health-interval 30s --health-timeout 5s \ --health-retries 3 --health-start-period 600s \ llamacpp:b10481 \ -m /jsxc/Qwen/Qwen3.8-27B-GGUF/Qwen3.8-27B-Q5_K_M.gguf \ --alias qwen3.8-27b \ --host 0.0.0.0 --port 8000 \ -ngl 99 -sm layer -fa on \ --ctx-size 524288 --no-context-shift \ --batch-size 2048 --ubatch-size 512 \ --parallel 2 --jinja --seed 3407 \ --temp 1.0 --top-p 0.95 --top-k 20 --min-p 0.0 --presence-penalty 0.0 ``` ### 5.2 每个非显然参数的理由 | 参数 | 为什么 | |------|--------| | `llamacpp:b10481` | 本地钉死的固定 tag(指向 5ebaf50acac4)。**不用浮动的 `server-cuda`**,避免以后被静默换成不兼容版本 | | `GGML_CUDA_DISABLE_GRAPHS=1` | 规避 Turing CUDA graphs 显存泄漏(#25835) | | `-v /data/nvcache38:/root/.nv` | 持久化 JIT 缓存,省掉每次冷启 1~2 分钟 | | `--health-cmd ...:8000/health` | **覆盖镜像内写死的 `localhost:8080`**。旧 `llm` 容器常年 unhealthy(FailingStreak 16000+)就是这个原因,不覆盖会掩盖真故障 | | `--health-start-period 600s` | 首次加载含 JIT + 20GB mmap,实测 82 秒,给足宽限 | | `--alias qwen3.8-27b` | 给下游稳定的 model id,避免文件名变更打穿调用方 | | `-ngl 99` | 该 build 的 `-ngl` 默认 `auto`、`--fit` 默认 `on`,不显式指定会为了塞下 ctx 把层甩到 CPU,**速度崩塌且不报错** | | `-sm layer` | 见 2.2 节,四卡无 P2P | | `-fa on` | Turing 有 head_dim=256 专用调优表,可放心开 | | `--batch-size 2048 --ubatch-size 512` | 比 3.6 的 4096/1024 保守;ubatch 直接决定 compute buffer 大小 | | 采样参数 | Qwen3.8 thinking 模式官方推荐 `temp 1.0 / top-p 0.95 / top-k 20 / min-p 0.0`。llama.cpp 默认是 `top_k=40 / min_p=0.05`,**不写就是错的**;也不要照抄 3.6 的 `0.7/40/0.01` | | 不挂 `--mmproj` | 首轮纯文本。mmproj 文件已下好在同目录,需要图像输入时再加 | | 不用 `--spec-type draft-mtp` | 见 2.1 节,sm_75 上不激活 | ### 5.3 显存实测(ctx=131072) ``` GPU0 7448 MiB GPU1 7336 MiB GPU2 8110 MiB GPU3 6532 MiB llm38 合计 29426 MiB / 88 GB ``` **低于 25 GB 说明有层落到 CPU 了**,回查 `-ngl` 与 `--fit`。 > KV cache 之所以小:64 层里只有 16 层是标准注意力(`full_attention_interval=4`),48 层是 Gated DeltaNet,KV 只有同规格纯注意力模型的约 27%。所以还有很大上下文余量:262144 约需 42 GB,524288 约需 59 GB。 ### 5.4 Thinking 模式与上下文语义(实测) **Thinking 默认开启**,思考过程走独立的 `reasoning_content` 字段,不混进 `content`: ```json {"messages":[...]} // 默认开启 {"messages":[...],"chat_template_kwargs":{"enable_thinking":false}} // 关闭 ``` 模板另支持 `reasoning_effort` 调节思考深度。 **★ `--ctx-size` 是总池不是单请求上限 ★** `--ctx-size` 给的是**总池**,被 `--parallel` 均分才是单请求上限。当前 `--ctx-size 524288 --parallel 2` → 每槽 **262144**(日志 `n_ctx_slot = 262144`)。 **模型原生上限是 262144,不是 131072。** 权威来源是 GGUF 元数据本身,别信二手说法: ```bash python3 /home/admin/qwen38-deploy/ggufmeta.py /data/models/Qwen/Qwen3.8-27B-GGUF/Qwen3.8-27B-Q5_K_M.gguf # qwen35.context_length = 262144 ← 原生上限 # qwen35.block_count = 65 (64 真实层 + 1 个未用的 nextn/MTP 层) # qwen35.full_attention_interval = 4 (64 层里只有 16 层是标准注意力) # qwen35.attention.head_count_kv = 4 / key_length = 256 / value_length = 256 ``` **KV 用量可以手算**:16 注意力层 × 4 KV 头 × 256 维 × 2(K+V)× 2 字节 = **64 KiB/token**。乘上总池 token 数就是 KV 显存,实测与估算吻合到 1 GB 以内。 | 配置 | 单请求上限 | 并发 | KV | 实测/估算总显存 | |------|-----------|------|-----|---------------| | `--parallel 4 --ctx-size 131072`(旧) | 32K | 4 | 8 GiB | 29.4 GB(实测) | | `--parallel 2 --ctx-size 524288`(**当前**) | **256K** | 2 | 32 GiB | **57.3 GB(实测)** | | `--parallel 1 --ctx-size 262144` | 256K | 1 | 16 GiB | ~38 GB | | `--parallel 4 --ctx-size 1048576` | 256K | 4 | 64 GiB | ~86 GB ❌ 放不下 | | 同上 + `-ctk q8_0 -ctv q8_0` | 256K | 4 | 32 GiB | ~55 GB(未验证) | **长上下文的真实成本**(实测,别只看显存放不放得下): | 提示长度 | 提示处理速度 | 光 prefill 耗时 | |---------|------------|---------------| | 11K | 1491 tok/s | 7.4 s | | 150K | 979 tok/s | 153 s | | 256K(外推) | ~950 tok/s | **~4.5 分钟** | prefill 期间独占一个槽位(共 2 个)。生成速度也随上下文下降:短上下文 23.4 tok/s,150K 时 16.7 tok/s。 **切换脚本**:`/home/admin/qwen38-deploy/ctx256k.sh`,自带失败自动回滚。 --- ### 5.5 如何调用(对外 API) **OpenAI 兼容**。model id 是 `qwen3.8-27b`(`--alias` 固定,不随权重文件名变)。 | 入口 | 地址 | 适用 | |---|---|---| | 公网 | `http://qwen.wudaima.com/v1` | 外网/办公网,经 FRP,仅 HTTP | | 内网 | `http://192.168.110.67:8000/v1` | 同局域网,直连更快 | | 本机 | `http://localhost:8000/v1` | SSH 进服务器后 | **无鉴权**——API key 随便填或不填都通(见第七节安全告警)。 ```bash curl http://qwen.wudaima.com/v1/chat/completions -H "Content-Type: application/json" -d '{ "model": "qwen3.8-27b", "messages": [{"role":"user","content":"你好"}], "max_tokens": 1024 }' ``` ```python from openai import OpenAI client = OpenAI(base_url="http://qwen.wudaima.com/v1", api_key="none") # key 必填但不校验 r = client.chat.completions.create(model="qwen3.8-27b", messages=[{"role":"user","content":"你好"}], max_tokens=1024) print(r.choices[0].message.content) ``` **四个调用方必须知道的点**: 1. **thinking 内容在 `reasoning_content` 字段,不在 `content`**。`max_tokens` 是两者之和——给小了会导致思考没结束就被截断,`content` 返回**空字符串**。要正常输出,`max_tokens` 给足(≥512),或用 `"chat_template_kwargs":{"enable_thinking":false}` 关掉思考。 2. **采样参数别自己传**。服务端已按 Qwen3.8 官方 thinking 推荐值启动(`temp 1.0 / top-p 0.95 / top-k 20 / min-p 0.0`),请求里再传会覆盖掉,容易传成 llama.cpp 的默认值(`top_k 40 / min_p 0.05`)而降质。 3. **`model` 字段不校验**。传错名字也返回 200 + 正常内容,所以别指望用它做健康检查——用 `/health` 或 `/v1/models`。 4. **长提示很贵**。256K 提示光 prefill 约 4.5 分钟且独占 1/2 槽位,客户端超时要放宽(`timeout=900`)。 常用端点:`/health`(存活)、`/v1/models`(模型 + `n_ctx`/`n_ctx_train`)、`/props`(`total_slots`、build 号)、`/v1/chat/completions`、`/v1/completions`。 --- ## 六、★ 回滚 ★ ```bash bash /home/admin/qwen38-deploy/restore.sh ``` 会清掉 `llm38`、用 `llamacpp-rollback:b9570` 镜像重建 `llm` 跑回 Qwen3.6-27B-IQ4_XS,约 3-5 分钟。 **回滚依赖三样东西,都不要删**: 1. 镜像 tag `llamacpp-rollback:b9570`(image id 9dad14fcc497) 2. 模型文件 `/data/models/Qwen/Qwen3.6-27B-GGUF/Qwen_Qwen3.6-27B-IQ4_XS.gguf` 3. 脚本 `/home/admin/qwen38-deploy/restore.sh` FRP/nginx 无需改动 —— 域名始终指向 `127.0.0.1:8000`。 --- ## 七、模型切换操作(vLLM 历史配置) > ⚠ `/home/admin/jiansuan/` 下的 vLLM compose 镜像是 v0.8.4 / v0.10.2(11~16 个月前),**不认识 Qwen3.5+ 的新架构**,只能跑 Qwen2.5 / DeepSeek 这些老模型。 ### 7.1 配置文件目录 ``` /home/admin/jiansuan/ ├── vllm/ │ ├── compose.72b.yaml # Qwen2.5-72B (vLLM) │ ├── compose.32b.yaml # DeepSeek-32B (vLLM) │ ├── compose.coder.30b.yaml # Qwen3-Coder-30B (vLLM) │ ├── compose.7b.1m.yaml # 7B 超长上下文 (vLLM, 只用 GPU2/3) │ └── compose.yaml # 基础模板(sleep,不自动启动) └── llama_cpp/ └── compose-qwen3-coder-next.yaml ``` 所有 compose 都用 `container_name: llm` + `ports: 8000:8000`,**同一时间只能跑一个**。切换前必须先 `docker stop llm38`。 ### 7.2 各 vLLM 配置要点 | 配置 | 模型 | 关键参数 | |------|------|----------| | `compose.72b.yaml` | Qwen2.5-72B-GPTQ-Int4 | `--dtype=half -tp 4 --gpu-memory-utilization 0.98 --max-model-len 32768` | | `compose.32b.yaml` | DeepSeek-R1-Distill-32B-AWQ | `--enable-reasoning --reasoning-parser deepseek_r1 -tp 4 --max-model-len 65536` | | `compose.coder.30b.yaml` | Qwen3-Coder-30B-A3B | `--enable-auto-tool-choice --tool-call-parser hermes -tp 4 --max-model-len 131072` | | `compose.7b.1m.yaml` | Qwen2.5-7B-1M | `--max-model-len 614400 --kv-cache-dtype fp8 -tp 2`,只用 GPU2/3 | 镜像统一为 `registry.cn-hangzhou.aliyuncs.com/jiansuan/vllm-openai:v0.8.4`,挂载 `/data/models:/root/models`。 ### 7.3 切换示例 ```bash cd /home/admin/jiansuan docker stop llm38 # 先停当前的 Qwen3.8 docker compose -f vllm/compose.72b.yaml up -d curl http://localhost:8000/v1/models # 预期 qwen2.5-72b ``` --- ## 八、反向代理配置 ### 8.1 FRP 内网穿透 **目录**:`/home/admin/llm/frp/` · **服务端**:`60.205.214.169:7009` · **由 PM2 管理**(God Daemon PID 1467) | 配置文件 | section | 域名 | 本地端口 | 状态 | |----------|---------|------|----------|------| | `frpc.qwen.ini` | `[qwen-llm]` | `qwen.wudaima.com` | 8000 | ✅ 大模型 API | | `frpc.qwen.ini` | `[qwen-console-subpath]` | `qwen.wudaima.com/console` | 8081 | ✅ h3-console 公网入口,要 Bearer token | | ~~`frpc.qwen.ini` `[qwen-gw-20260610]`~~ | ~~`gateway.wudaima.com`~~ | ~~8080~~ | **2026-08-29 已删除**:这条隧道客户端配置指向 8080(h3-console 局域网实例),域名一直没打到我们(frp 服务端 `60.205.214.169` 没配对应 vhost,实测落在一个无关的默认 nginx 页面),但客户端配置本身是活的隐患——一旦服务端哪天补上 vhost 就会瞬间暴露开着弹性调度器的局域网实例。删前备份在服务器 `/home/admin/llm/frp/frpc.qwen.ini.bak-20260829` | | `frpc.ini` | `[m3e]` | `m3e.embedding.wudaima.com` | 7590 | ✅ 嵌入服务 | | `sd.frpc.ini` | `[stable-diffusion-web]` | `stable-diffusion.wudaima.com` | 7860 | ✅ SD WebUI | | `comfyui.frpc.ini` | `[comfyui-web]` | `comfyui.wudaima.com` | 8188 | ✅ **2026-08-22 起 raylight 常驻监听 8188,隧道其实一直是活的**(旧结论"无监听隧道空挂"已过期);**2026-08-29 补了 `http_user`/`http_pwd` 基本认证**(ini 里的原生字段,不用改 ComfyUI 代码),之前裸奔过一段时间见 `CHANGELOG.md` | | `ssh.frpc.ini` | `[ssh]` | — (tcp) | 22 → 公网 6000 | ⚠ **SSH 暴露公网** | ```bash pm2 list # 需先 export PATH 或用绝对路径 pm2 logs frpc-qwen-client --lines 50 ``` > ⚠ **安全**:`qwen.wudaima.com` 无任何鉴权,公网可直接调用本机 27B 推理(llm38 目前已停,暂时不可利用)。`qwen.wudaima.com/console`(h3-console 公网入口)**2026-08-29 起要求 `Authorization: Bearer `**,token 见 `h3-console/README.md`。`gateway.wudaima.com → 8080` 那条隐患隧道 2026-08-29 已删除,见上表。SSH 映射到公网 6000 且允许密码登录、admin 在 sudo 组。 ### 8.2 Nginx **配置目录**:`/etc/nginx/conf.d/` | 文件 | 监听 | 静态根 | 后端 | |------|------|--------|------| | `farm.conf` | `:4016` | `/home/admin/chat/chatbot-front/dist` | `127.0.0.1:4017` + `127.0.0.1:4020` | | `manage.conf` | `:4018` | `/home/admin/chat/manage-front/dist` | `127.0.0.1:4019` + `127.0.0.1:4020` | > ⚠ **已知故障**:`4017` / `4019` / `4020` **三个后端端口全部无监听**。两个前端静态页能打开,但任何 API 请求都会 502。聊天应用目前是坏的。 ### 8.3 AutoSSH `/etc/systemd/system/autossh.service` —— 状态 `active` + `enabled`,把本机 22 反向代理到 AWS: ```bash autossh -N -M 0 -R 10044:localhost:22 ubuntu@2404:c2c0:8522:c100:f7b:8b85:5fec:e174 ``` --- ## 九、LLM Farm 应用栈 **目录**:`/data/models/llmfarm/` · Compose:`docker-compose.yml` 服务:`chatbot-frontend`(:10000) · `chatbot-backend` · `chatbot-mysql`(:3306, 密码 `Chain.123456`) · `chatbot-chain` · `chatbot-chroma`(:8000 仅容器内网) · `chatbot-management-frontend`(:9999) · `chatbot-management-backend` > Chroma 也用 8000,但只在 Docker 内部网络;大模型容器绑的是 `0.0.0.0:8000`,不冲突。 --- ## 十、常用命令速查 ```bash # ---- 状态 ---- nvidia-smi docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}" docker logs llm38 --tail 100 -f curl -s http://localhost:8000/v1/models | python3 -m json.tool curl -s http://localhost:8000/health # ---- 对话测试(model 字段可任意,服务端不校验)---- cat > /tmp/t.json <<'EOF' {"messages":[{"role":"user","content":"你好"}],"max_tokens":200} EOF curl -s http://localhost:8000/v1/chat/completions -H "Content-Type: application/json" -d @/tmp/t.json # ---- 新模型上线前必查(血泪教训)---- docker run --rm --entrypoint /app/llama-server <镜像> --version # build 必须 >= 10450 docker run --rm --entrypoint /app/llama-server <镜像> --help | grep -- '--某参数' # 新版对未知参数是 throw 不是忽略 sha256sum /data/models/.../xxx.gguf # 与 HF 官方值比对 # ---- 显存核对 ---- nvidia-smi --query-gpu=index,memory.used,memory.free --format=csv nvidia-smi --query-compute-apps=pid,used_memory --format=csv # ---- 回滚 ---- bash /home/admin/qwen38-deploy/restore.sh # ---- 外部验证 ---- curl -s http://qwen.wudaima.com/v1/models | python3 -m json.tool ``` --- ## 十一、目录速查表 | 用途 | 路径 | |------|------| | 模型文件 | `/data/models/` | | **Qwen3.8 部署脚本** | `/home/admin/qwen38-deploy/` | | JIT 缓存 | `/data/nvcache38/` | | vLLM / llama.cpp Compose | `/home/admin/jiansuan/vllm/`、`/home/admin/jiansuan/llama_cpp/` | | FRP 客户端 | `/home/admin/llm/frp/` | | Nginx 配置 | `/etc/nginx/conf.d/` | | AutoSSH 服务 | `/etc/systemd/system/autossh.service` | | LLM Farm Compose | `/data/models/llmfarm/docker-compose.yml` | | 本备忘文档 | `/home/admin/llm-setup.md` | --- ## 十二、注意事项 1. **上新模型前先读第二、三节**。FP8 装不了、build 有下限、HF 连不上 —— 这三条能省掉大半天。 2. **`unhealthy` 不再是"正常现象"**。旧文档说 llama.cpp 容器常显示 unhealthy 不影响使用 —— 那是因为镜像内 healthcheck 写死了 `localhost:8080` 而服务在 8000。`llm38` 已用 `--health-cmd` 覆盖,现在 `healthy` 是真的健康、`unhealthy` 是真的有问题。 3. **FRP 域名固定**:`qwen.wudaima.com` 始终指向 `127.0.0.1:8000`,切换模型后域名不变,但 `/v1/models` 返回的 model id 会变。服务端**不校验**请求里的 model 字段,下游硬编码旧模型名也不会报错。 4. **磁盘**:`/` 只剩 29G(87%),docker 镜像和日志都写这里,留意别写满。`/data` 还有 353G。 5. **GPU 占用基线**(起大模型前先看):GPU0 有 embedding(668M)+SD(174M),GPU3 有 whisper(3258M)。这些常驻进程会让默认 tensor-split 算错,见 2.2 节。 6. **不要同时起两个 27B**。四卡总量够,但计算争用会让对外服务吞吐腰斩,且 GPU3 余量不足会 OOM。要并行验证请用 `--device CUDA0,CUDA1,CUDA2` 避开 GPU3 并把 ctx 砍到 32768。