跳转至内容
  • 版块
  • 最新
  • 标签
  • 热门
  • 用户
  • 群组
皮肤
  • 浅色
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • 深色
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • 默认(LCZ-Blue)
  • 不使用皮肤
  • LCZ-Green
  • LCZ-Blue
  • LCZ-Black
折叠
品牌标识

抡锤者

首页 版块 标签
硬件
装备秀
AI 广场 App
  1. 主页
  2. 版块
  3. LLM讨论区
  4. Tesla V100-32G 跑 Qwen3.8-27B nvfp4:200W 下 decode 93.9 tok/s、prefill 1019 tok/s(NInfer SM70 / CUDA 12.8)

Tesla V100-32G 跑 Qwen3.8-27B nvfp4:200W 下 decode 93.9 tok/s、prefill 1019 tok/s(NInfer SM70 / CUDA 12.8)

已定时 已固定 已锁定 已移动 LLM讨论区
v100qwen-27b本地模型
2 帖子 1 发布者 309 浏览
  • 从旧到新
  • 从新到旧
  • 最多赞同
回复
  • 在新帖中回复
登录后回复
此主题已被删除。只有拥有主题管理权限的用户可以查看。
  • D
    D
    davidwei0826
    体面乡绅
    编写于 最后由 编辑
    #1

    成绩速览(V100-PCIE-32G / 200W / 单请求)

    指标 最好 区间
    decode 93.9 tok/s(编码任务,640 token,MTP 接受率 92%) 44.9–93.9 tok/s(取决于任务与 MTP 接受率)
    prefill 1,019.0 tok/s(7.9K prompt) 505.8–1,019.0 tok/s(随上下文深度衰减)
    TTFT 0.13 s(完全相同的 prompt 重发,前缀 100% 命中) 0.18–0.47 s(短 prompt)→ 1.96 s @2K → 250.27 s @128K
    并发 2 路各 124.6K 上下文实测跑通 第二路排队 4m1.1s(prefill 串行)
    显存 权重 19.7 GiB + KV 池 262,144 token 启动后 free 1.21 GiB

    这篇针对 neroued/Qwen3.8-27B-nvfp4-NInfer 这个 nvfp4 制品,写两件事:
    ① 完整部署流程(含源码锚点、Dockerfile、制品下载校验、启动脚本、报错对照),别人或别人的 agent 照着能直接跑起来;
    ② 全部实测数字(上下文 / 制品 A/B / 任务类型 / 并发 / 显存容量 / 前缀复用),只列数据,结论很少。

    给 agent / 想直接照做的人:把第 3 节那个脚本原样存成 deploy-v100-nvfp4.sh,sudo bash 跑完即可(驱动、Docker、CUDA 12.8、编译引擎、打镜像、下制品校验、启动、健康检查全在里面)。
    所有锚点都已钉死:引擎 repo + commit、制品 repo + revision + sha256、镜像底座、启动参数。文中标注 ⚠️ 的四处是必须照做的(非 open 驱动 / v2 容器制品 / 显式 --kv-capacity / --pending-timeout-ms),踩错会直接报错或起不来。


    0. 环境

    项 值
    GPU Tesla V100-PCIE-32GB(GV100,Volta SM70,32G HBM2,PCIe Gen3 x16)
    形态 PVE 直通给 Ubuntu 24.04 VM(16 vCPU / 32G RAM / 200G 系统盘)
    宿主 CPU Xeon E5-2697 v4 @2.30GHz ×16(Broadwell,无 AVX-512)
    驱动 580.178.04(非 open)
    功率墙 200 W(V100-PCIE 默认 250 W)
    引擎 NInfer V100/sm_70 分支,hamawang/ninfer-v100-20260916 @ f17d37fc98b78cc025a1037e8adb1f4fb83813fb
    编译 CUDA 12.8,-DCMAKE_CUDA_ARCHITECTURES=70
    容器底座 nvidia/cuda:12.8.0-runtime-ubuntu24.04
    制品 qwen3_8_27b_nvfp4.ninfer(20.02 GiB,container_version 2)
    运行参数 --max-context 131072 --kv-capacity 262144 --max-concurrency 2 --kv-dtype int8
    实测占用 权重 19.7 GiB,KV 池 262,144 token,运行时 10.8 GiB,启动后 free 1.21 GiB,ready 18.2 s

    1. 部署

    1.1 驱动(Volta 必须非 open)

    sudo apt-get install -y "linux-headers-$(uname -r)" nvidia-driver-580-server
    sudo modprobe nvidia && nvidia-smi -L
    sudo nvidia-smi -pm 1 && sudo nvidia-smi -pl 200
    
    • -open 内核模块只支持 Turing 及更新架构,Volta 装上会报
      not supported by open nvidia.ko ... does not include the required GPU System Processor (GSP)。
    • R580 是 Maxwell / Pascal / Volta 的最后一条驱动分支。
    • nvidia-smi -pl 不跨重启保留,需要开机重施(附脚本里给了 systemd oneshot 单元)。

    1.2 引擎源码与构建

    git clone https://github.com/hamawang/ninfer-v100-20260916.git /opt/ninfer-v100
    cd /opt/ninfer-v100 && git checkout f17d37fc98b78cc025a1037e8adb1f4fb83813fb
    
    # 需要 CUDA 12.8 toolkit(CUDA 13 已移除 Volta 的离线编译)
    bash deploy-v100/scripts/build-v100.sh
    #   = cmake -S . -B build-v100 -G Ninja -DCMAKE_BUILD_TYPE=Release \
    #       -DCMAKE_CUDA_COMPILER=/usr/local/cuda-12.8/bin/nvcc \
    #       -DCMAKE_CUDA_ARCHITECTURES=70 -DNINFER_BUILD_BENCHMARKS=ON
    #     cmake --build build-v100 -j6
    

    产物(可用于校验你自建的二进制,同 commit + CUDA 12.8 + sm_70):

    371fd8de37e73df12b1f61144e43b210a12f9c0ef4acc193f5ae3f11f4294658  build-v100/apps/ninfer
    6671447e3cbbf07565dff9417462d01bcf8aa1093aa5c9f83fb6a9a0ce79ac10  build-v100/apps/ninfer-serve
    

    1.3 打镜像(完整 Dockerfile)

    底座必须与制品编译时的 CUDA 版本对齐(二进制 RUNPATH 硬指 /usr/local/cuda-12.8/...):

    FROM nvidia/cuda:12.8.0-runtime-ubuntu24.04
    
    ARG DEBIAN_FRONTEND=noninteractive
    
    # base 镜像只带 NVIDIA 源、没有 Ubuntu 归档,先换源再装运行库
    RUN rm -f /etc/apt/sources.list.d/ubuntu.sources 2>/dev/null; \
        printf '%s\n' \
          'Types: deb' \
          'URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu' \
          'Suites: noble noble-updates noble-backports' \
          'Components: main universe restricted multiverse' \
          'Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg' \
          '' \
          'Types: deb' \
          'URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu' \
          'Suites: noble-security' \
          'Components: main universe restricted multiverse' \
          'Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg' \
          > /etc/apt/sources.list.d/ubuntu.sources \
        && apt-get update -qq \
        && apt-get install -y --no-install-recommends \
            ca-certificates libavcodec60 libavformat60 libavutil58 \
            libswscale7 libswresample4 libcurl4t64 \
        && rm -rf /var/lib/apt/lists/*
    
    COPY ninfer ninfer-serve /usr/local/bin/
    RUN chmod +x /usr/local/bin/ninfer /usr/local/bin/ninfer-serve
    
    WORKDIR /workspace
    EXPOSE 8080
    CMD ["ninfer-serve", "--help"]
    
    mkdir -p ctx && cp /opt/ninfer-v100/build-v100/apps/{ninfer,ninfer-serve} ctx/
    docker build -t ninfer-v100:0.1.0 ctx/
    

    libcuda.so.1 不打进镜像,由 --gpus 从宿主驱动注入(镜像与驱动版本解耦)。

    1.4 下载 nvfp4 制品(必须钉这个 revision)

    mkdir -p /srv/models && cd /srv/models
    curl -L -C - -o qwen3_8_27b_nvfp4.ninfer \
      "https://hf-mirror.com/neroued/Qwen3.8-27B-nvfp4-NInfer/resolve/204e3d92c30d9d05f3300d2f52e443ad1edf6ddf/qwen3_8_27b_nvfp4.ninfer"
    
    # 校验(必须一致,否则说明下错版本)
    sha256sum qwen3_8_27b_nvfp4.ninfer
    # bb3360522a06e136e0367f5703414d26272b7285c8a6ab6194135c17dbd81b32
    
    字段 值
    repo neroued/Qwen3.8-27B-nvfp4-NInfer
    revision(钉死) 204e3d92c30d9d05f3300d2f52e443ad1edf6ddf(2026-08-19)
    文件 / 字节 qwen3_8_27b_nvfp4.ninfer / 21,492,695,040(20.02 GiB)
    sha256 bb3360522a06e136e0367f5703414d26272b7285c8a6ab6194135c17dbd81b32
    container_version 2

    为什么不能下 main:仓库 main(a107ba1b)上的同名文件是 container v3(23,719,496,192 B),本引擎只认 v2,加载直接失败:

    ERROR startup failed | inspecting artifact | 31.4 ms
    FATAL server failed during startup | artifact magic is not NInfer v2
    

    容器版本看文件头 8 字节即可判断:

    dd if=qwen3_8_27b_nvfp4.ninfer bs=1 count=8 status=none | od -c
    # 正确: N I N F E R \0 002
    # v3  : N I N F E R \0 003
    

    实测下载速度(HF 官方站不可达时用 hf-mirror):12.4 MB/s,20 GiB 约 29 分钟;curl -C - 支持断点续传。
    制品建议放本地盘:本地盘加载 18.2 s,走 NFS 是 52–59 s。

    1.5 启动脚本(可直接用)

    #!/usr/bin/env bash
    # ninfer-v100 run.sh —— nvfp4 + 2 并发 × 128K
    set -euo pipefail
    
    NAME=ninfer
    IMG=ninfer-v100:0.1.0
    MODEL_DIR=${MODEL_DIR:-/srv/models}
    MODEL=${MODEL:-qwen3_8_27b_nvfp4.ninfer}
    PORT=${PORT:-18080}
    CTX=${CTX:-131072}          # 单请求逻辑上下文上限
    KV_CAP=${KV_CAP:-262144}    # ★ 共享 KV 池,必须显式给 = 2 × CTX
    CONC=${CONC:-2}             # 并发路数
    PREFILL=${PREFILL:-2048}    # V100 推荐
    PENDING_MS=${PENDING_MS:-600000}   # ★ 默认 30s 会把并发长请求挤成 503
    API_KEY=${API_KEY:-}        # 留空 = 不鉴权
    
    ARGS=(--host 0.0.0.0 --port 8080
          --max-context "$CTX" --kv-capacity "$KV_CAP" --max-concurrency "$CONC"
          --kv-dtype int8 --prefill-chunk "$PREFILL" --pending-timeout-ms "$PENDING_MS"
          --spec mtp --draft-tokens 3 --lm-head-draft
          --preserve-thinking --cors)
    [ -n "$API_KEY" ] && ARGS+=(--api-key "$API_KEY")
    
    case "${1:-start}" in
      start)
        docker rm -f "$NAME" >/dev/null 2>&1 || true
        docker run -d --name "$NAME" --restart unless-stopped \
          --gpus all --ipc=host \
          -e NVIDIA_VISIBLE_DEVICES=all -e NVIDIA_DRIVER_CAPABILITIES=compute,utility \
          -p "${PORT}":8080 -v "$MODEL_DIR":/models:ro \
          "$IMG" ninfer-serve "/models/$MODEL" "${ARGS[@]}"
        echo "started -> http://0.0.0.0:${PORT}"
        ;;
      stop)    docker stop -t 30 "$NAME";;
      logs)    docker logs -f --tail 100 "$NAME";;
      status)  docker ps -a --filter "name=^${NAME}$";;
      *) echo "usage: $0 {start|stop|logs|status}"; exit 1;;
    esac
    

    参数说明(都是实测踩出来的)

    参数 为什么是这个值
    --max-context 131072 128K 逻辑上限。超限请求被明确拒绝而不是截断:400 context_length_exceeded: prepared prompt exceeds Engine max_context 131072
    --kv-capacity 262144 必须显式。nvfp4 权重 19.7 GiB 下 auto 只肯给 ~237K,而且 auto 模式要额外留 1 GiB headroom → 直接拒绝启动。显式 262144 正好 = 2×128K,实测启动后 free 1.21 GiB
    --max-concurrency 2 引擎真批处理路数。客户端并发超过它会被饿(实测第 3、4 条掉到 5.7 tok/s)
    --kv-dtype int8 Volta 没有 fp8 / nvfp4 / k8v4 的 KV 内核,只能 bf16 或 int8
    --prefill-chunk 2048 V100 上的推荐值
    --pending-timeout-ms 600000 默认 30 s。prefill 是单通道串行的,一条 125K prompt 要 prefill 4 分钟,第二路在队列里等超过 30 s 就被判 503 request_queue_timeout
    --spec mtp --draft-tokens 3 --lm-head-draft MTP 投机解码;decode 快慢几乎完全由它的接受率决定(见第 2.3 节)

    1.6 验收

    curl -s localhost:18080/health          # {"status":"ok"}
    curl -s localhost:18080/v1/models       # max_model_len = 131072
    
    curl -s localhost:18080/v1/chat/completions -H 'Content-Type: application/json' -d '{
      "model":"qwen3.8-27b",
      "messages":[{"role":"user","content":"只回答两个字:收到"}],
      "max_tokens":16,"reasoning_effort":"none"}' | head -c 200
    

    启动日志里会打出显存账本(--log-level debug 更详细):

    INFO  engine ready | qwen3.8-27b/nvfp4 | total 18.2s | weights 19.7 GiB
    INFO  capacity | KV 262,144 tokens, int8, explicit | pages 4,096/4,096 | runtime 10.8 GiB | free 1.21 GiB
    INFO  listening on http://0.0.0.0:8080 | model qwen3.8-27b | auth disabled
    

    1.7 报错对照表

    现象 根因 处置
    nvidia-smi: couldn't communicate with the NVIDIA driver / nvtop 看不到卡 驱动没装(直通本身没问题,lspci 能看到 10de:1db6) 装 nvidia-driver-580-server
    not supported by open nvidia.ko ... GPU System Processor (GSP) 装了 -open 驱动,Volta 不支持 换非 open:apt purge "nvidia-*-open" 再装 nvidia-driver-580-server
    cannot open shared object file: libcudart.so.12 底座 CUDA 版本与二进制 RUNPATH 不一致 底座用 cuda:12.8.0-runtime-ubuntu24.04
    FATAL ... artifact magic is not NInfer v2 下了 v3 容器制品(main 上的那个) 钉 revision 204e3d92c30d(v2 容器)
    minimum Engine runtime reservation requires … but only … available after weights 显存不够(auto 模式还要额外 1 GiB) 显式给 --kv-capacity,并按下表算容量
    503 request_queue_timeout 默认 30 s 排队超时 + prefill 串行 --pending-timeout-ms 600000
    400 context_length_exceeded prompt + 输出超过 --max-context 调小 prompt 或调大 --max-context(受显存限制,见 2.5)

    2. Benchmark

    统一条件:贪心(temperature=0)、reasoning_effort: none(除注明)、prompt 为同一份技术文档按目标长度拼接;decode = 引擎口径「已提交输出 token / 秒」;TTFT = 服务端 prompt 处理时间(不含排队);功率墙 200 W;负载期功耗中位 195 W、SM 频率中位 1087 MHz(最高 1380 MHz)。

    2.1 上下文长度扫描(nvfp4 制品,单请求,128 输出 token)

    目标上下文 prompt token prefill tok/s TTFT decode tok/s MTP 接受率
    2K 1,967 1,003.5 1.96 s 56.8 47%(38/81)
    8K 7,907 1,019.0 7.76 s 72.6 71%(45/63)
    32K 31,667 868.6 36.46 s 57.2 60%(45/75)
    64K 63,311 699.4 90.52 s 36.2 40%(37/93)
    128K 126,599 505.8 250.27 s 37.0 60%(45/75)

    补充:同一配置下 8K prompt、320 输出上限的持续生成实测 71.5 tok/s(MTP 71%)。

    2.2 nvfp4 vs groupwise-int(同一脚本、同一参数,唯一变量是制品)

    neroued/Qwen3.8-27B-NInfer @ 18dfc887423f(groupwise-int,16.96 GiB,sha256 eec39564993d…4bf3e)作为对照:

    shape groupwise-int:prefill / decode / MTP nvfp4:prefill / decode / MTP
    1K 987.9 / 41.8 / 51% 1,003.5 / 56.8 / 47%
    7K 1,014.0 / 43.3 / 58% 1,019.0 / 72.6 / 71%
    30K 864.7 / 42.4 / 65% 868.6 / 57.2 / 60%
    61K 696.3 / 31.3 / 52% 699.4 / 36.2 / 40%
    123K 505.9 / 29.5 / 63% 505.8 / 37.0 / 60%
    编码任务(640 tok,两边 MTP 都 89%) 115.2 / 58.6 / 89% 119.5 / 90.9 / 89%
    持续生成(8K,66 tok) 951.1 / 41.6 / 58% 954.5 / 71.5 / 71%
    双并发(8K,均缓存命中) 批 wall 3.84 s / 188 tok / 48.9 tok/s 批 wall 2.55 s / 152 tok / 59.7 tok/s

    上下文扫描那几行的 decode 不能直接横向比:权重不同 → 生成的文本不同 → MTP 接受率不同(40% vs 52% 之类),短样本下接受率差异会盖过真实速度差。编码任务那行是干净的(prompt、输出长度 640、贪心、MTP 接受率 464/523 vs 467/525 全部对齐):58.6 → 90.9 tok/s。
    注:这张表的数字来自成对跑的那一轮;同一 prompt 在 2.3 节另一轮里测得 93.4/93.9 tok/s(MTP 91–92%),两轮差异属运行间波动(同一制品重跑 ±3%)。

    2.3 任务类型(nvfp4,8K 与 64K 两档)

    任务 输出 token 8K:decode / MTP 64K:decode / MTP
    写代码(LRU + pytest) 640 93.4 / 91% 93.9 / 92%
    JSON 字段抽取 24 82.7 / 90% 82.7 / 90%
    摘要(5.9K 文档) 56 81.2 / 81% 81.4 / 81%
    翻译 48 78.7 / 76% 78.3 / 76%
    推理(effort=xhigh,1024 思考 token) 1024 70.8 / 61% 70.6 / 61%
    找 bug 根因(闭包 late-binding) 253 68.8 / 57% 68.8 / 57%
    闲聊 92 55.8 / 42% 55.9 / 42%
    写小说 257 44.9 / 26% 47.5 / 31%

    TTFT 方面:短 prompt(几十 token)在 8K 与 64K 档几乎无差别(0.09–0.47 s),只有 5.9K 文档摘要那档是 5.8 s。

    2.4 并发

    (a)双并发长上下文(本机生产配置实测,2 路各 ~125K)

    路 prompt token TTFT(服务端) 其中排队 prefill tok/s 输出 wall
    L1 124,632 241.0 s 0 517 61 319.9 s
    L2 124,632 247.6 s(引擎记 8m8.7s) 4 m 1.1 s 503 61 490.9 s

    (b)解码批处理(引擎 5 s 窗口口径,groupwise 制品同引擎测得)

    batch 聚合 decode tok/s 相对 batch=1
    1.00 60.4 1.00×
    2.00 87.2 1.44×
    3.98 126.8 2.10×

    (c)端到端(每路冷启动 8K prompt + 320 输出 token,groupwise 制品)

    服务端并发 客户端路数 单路端到端 聚合端到端 加速比
    2 1 24.4 tok/s 24.4 1.00×
    2 2 24.0–24.6 26.5–27.2 1.11×
    4 4 23.9 29.3 1.22×

    (d)服务端日志里的两个并发现象(原文)

    # prefill 单通道串行:任一瞬间只有 1 路在 prefill,其他在等
    throughput | 5.0s | prefill 409.6 tok/s (2,048 tok) | running 1 (prefill 1) | waiting 1 | host 53.9%
    
    # prefill 会饿死 decode:有 prefill 时 decode 掉到个位数
    throughput | 5.0s | prefill 819.2 tok/s (4,096 tok) | decode  3.2 tok/s | running 3 (prefill 1, decode-ready 2) | batch 2.00
    throughput | 5.0s |                              | decode 126.8 tok/s | running 4 (decode-ready 4)              | batch 3.98
    

    2.5 显存与容量(这块最实用)

    用失败报错反解出的引擎显存公式(32G V100,int8 KV,MTP3):

    运行时占用 = 2.75 GiB(固定:state 槽 + workspace + CUDA graph) + KV 池容量 × 35,904 B
    权重后可用显存:nvfp4 11.70 GiB / groupwise-int 14.75 GiB
    

    实测容量上限(--max-concurrency 2,容量需为 64 的倍数,均为「能启动 + 能跑通请求」验证过的值):

    groupwise-int nvfp4
    权重 16.7 GiB 19.7 GiB
    权重后可用 14.75 GiB 11.70 GiB
    --kv-capacity auto 328,960 token ❌ 拒绝启动(差 0.88 GiB)
    最大共享池 358,912 token 267,456 token
    双并发每路可用 ≈179K ≈130K
    2×160K(池需 327,680) ✅ 余 31,232 ❌ 差 2.01 GiB;关掉 graph + state 槽也只省 622 MiB,仍差 1.40 GiB

    单请求边界(--max-context 131072):

    HTTP 400 {"error":{"code":"context_length_exceeded",
      "message":"prepared prompt exceeds Engine max_context 131072", ...}}
    

    2.6 前缀复用(同引擎,16K 文档)

    (同一组测量:16K 文档,prompt 15,846–15,886 token,同引擎)

    场景 prompt token 命中前缀 token TTFT
    冷请求 15,846 0 16.47 s
    完全相同请求重发 15,846 15,839(100%) 0.13 s
    同 prompt、只改 max_tokens(64 → 256) 15,846 15,839(100%) 0.13 s
    prompt 后追加一句(Chat Completions) 15,855 0 16.72 s
    同正文、换会话编号 15,846 0 16.80 s
    显式 prompt_cache_breakpoint 写入后再追加读取 15,855 0 17.00 s
    Anthropic cache_control 写入 → 追加读取 15,886 15,879 1.65 s
    Responses API previous_response_id 续轮 — 15,917 1.17 s

    2.7 运行条件

    项 值
    功率墙 200 W(默认 250 W,可设 100–250)
    负载期功耗 中位 195 W,最高 228 W
    负载期 SM 频率 中位 1087 MHz,最高 1380 MHz(卡的最大 SM 时钟即 1380)
    空载 37–40 °C / 约 60 W
    PCIe Gen3 x16(8 GT/s),非瓶颈

    3. 一键部署脚本

    #!/usr/bin/env bash
    # ============================================================
    #  NInfer + Qwen3.8-27B (nvfp4) @ Tesla V100-PCIE-32GB
    #  CUDA 12.8 / sm_70 / Docker / 200W / 2 并发 × 128K
    #  用法: sudo bash deploy-v100-nvfp4.sh
    # ============================================================
    set -euo pipefail
    MODEL_DIR=${MODEL_DIR:-/srv/models}
    PORT=${PORT:-18080}; CTX=${CTX:-131072}; KV_CAP=${KV_CAP:-262144}
    CONC=${CONC:-2};   POWER_LIMIT=${POWER_LIMIT:-200}
    SRC_DIR=${SRC_DIR:-/opt/ninfer-v100}; CUDA_ROOT=${CUDA_ROOT:-/usr/local/cuda-12.8}
    REPO=https://github.com/hamawang/ninfer-v100-20260916.git
    COMMIT=f17d37fc98b78cc025a1037e8adb1f4fb83813fb
    ART_URL=https://hf-mirror.com/neroued/Qwen3.8-27B-nvfp4-NInfer/resolve/204e3d92c30d9d05f3300d2f52e443ad1edf6ddf/qwen3_8_27b_nvfp4.ninfer
    ART_SHA=bb3360522a06e136e0367f5703414d26272b7285c8a6ab6194135c17dbd81b32
    IMG=ninfer-v100:0.1.0
    step(){ echo; echo "==== $* ===="; }
    
    step "1/6 NVIDIA 驱动(非 open)+ 功率墙"
    if ! command -v nvidia-smi >/dev/null 2>&1; then
      apt-get update -qq && apt-get install -y "linux-headers-$(uname -r)" nvidia-driver-580-server
      modprobe nvidia 2>/dev/null || { echo "驱动已装,请重启后重新运行本脚本"; exit 0; }
    fi
    nvidia-smi -L
    nvidia-smi -pm 1 && nvidia-smi -pl "$POWER_LIMIT"
    # 功率墙不跨重启,落一个开机单元
    cat > /usr/local/bin/nvidia-powerlimit.sh <<'EOF'
    #!/bin/bash
    for _ in $(seq 1 60); do nvidia-smi -L >/dev/null 2>&1 && break; sleep 5; done
    nvidia-smi -pm 1 >/dev/null 2>&1 || true
    nvidia-smi -pl "${1:-200}"
    EOF
    chmod +x /usr/local/bin/nvidia-powerlimit.sh
    
    step "2/6 Docker + nvidia-container-toolkit"
    if ! command -v docker >/dev/null 2>&1; then
      install -m 0755 -d /etc/apt/keyrings
      curl -fsSL https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu/gpg \
        | tee /etc/apt/keyrings/docker.asc >/dev/null && chmod a+r /etc/apt/keyrings/docker.asc
      echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu $(. /etc/os-release; echo "$VERSION_CODENAME") stable" \
        > /etc/apt/sources.list.d/docker.list
      apt-get update -qq && apt-get install -y docker-ce docker-ce-cli containerd.io
    fi
    if ! command -v nvidia-ctk >/dev/null 2>&1; then
      apt-get update -qq && apt-get install -y nvidia-container-toolkit || {
        curl -fsSLO https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2404/x86_64/cuda-keyring_1.1-1_all.deb
        dpkg -i cuda-keyring_1.1-1_all.deb && apt-get update -qq && apt-get install -y nvidia-container-toolkit; }
    fi
    nvidia-ctk runtime configure --runtime=docker
    systemctl enable --now docker && systemctl restart docker
    
    step "3/6 CUDA 12.8 toolkit(编译引擎)"
    if [ ! -x "$CUDA_ROOT/bin/nvcc" ]; then
      curl -fsSLO https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2404/x86_64/cuda-keyring_1.1-1_all.deb
      dpkg -i cuda-keyring_1.1-1_all.deb && apt-get update -qq
      apt-get install -y cuda-toolkit-12-8
    fi
    "$CUDA_ROOT/bin/nvcc" --version | tail -1
    
    step "4/6 构建引擎"
    if [ ! -x "$SRC_DIR/build-v100/apps/ninfer-serve" ]; then
      command -v cmake >/dev/null 2>&1 && command -v ninja >/dev/null 2>&1 || apt-get install -y cmake ninja-build git
      [ -d "$SRC_DIR/.git" ] || git clone "$REPO" "$SRC_DIR"
      git -C "$SRC_DIR" checkout "$COMMIT"
      ( cd "$SRC_DIR" && CUDA_ROOT="$CUDA_ROOT" bash deploy-v100/scripts/build-v100.sh )
    fi
    sha256sum "$SRC_DIR"/build-v100/apps/ninfer "$SRC_DIR"/build-v100/apps/ninfer-serve
    
    step "5/6 打镜像 + 下制品"
    CTXDIR=$(mktemp -d)
    cp "$SRC_DIR"/build-v100/apps/{ninfer,ninfer-serve} "$CTXDIR"/
    cat > "$CTXDIR/Dockerfile" <<'EOF'
    FROM nvidia/cuda:12.8.0-runtime-ubuntu24.04
    ARG DEBIAN_FRONTEND=noninteractive
    RUN rm -f /etc/apt/sources.list.d/ubuntu.sources 2>/dev/null; \
        printf '%s\n' 'Types: deb' 'URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu' \
          'Suites: noble noble-updates noble-backports' 'Components: main universe restricted multiverse' \
          'Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg' '' \
          'Types: deb' 'URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu' 'Suites: noble-security' \
          'Components: main universe restricted multiverse' \
          'Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg' \
          > /etc/apt/sources.list.d/ubuntu.sources \
        && apt-get update -qq \
        && apt-get install -y --no-install-recommends ca-certificates \
            libavcodec60 libavformat60 libavutil58 libswscale7 libswresample4 libcurl4t64 \
        && rm -rf /var/lib/apt/lists/*
    COPY ninfer ninfer-serve /usr/local/bin/
    RUN chmod +x /usr/local/bin/ninfer /usr/local/bin/ninfer-serve
    WORKDIR /workspace
    EXPOSE 8080
    EOF
    docker build -t "$IMG" "$CTXDIR"
    mkdir -p "$MODEL_DIR"
    if [ ! -f "$MODEL_DIR/qwen3_8_27b_nvfp4.ninfer" ]; then
      curl -L -C - -o "$MODEL_DIR/qwen3_8_27b_nvfp4.ninfer" "$ART_URL"
    fi
    echo "$ART_SHA  $MODEL_DIR/qwen3_8_27b_nvfp4.ninfer" | sha256sum -c -
    
    step "6/6 启动"
    docker rm -f ninfer >/dev/null 2>&1 || true
    docker run -d --name ninfer --restart unless-stopped --gpus all --ipc=host \
      -e NVIDIA_VISIBLE_DEVICES=all -e NVIDIA_DRIVER_CAPABILITIES=compute,utility \
      -p "${PORT}":8080 -v "$MODEL_DIR":/models:ro "$IMG" \
      ninfer-serve /models/qwen3_8_27b_nvfp4.ninfer \
        --host 0.0.0.0 --port 8080 \
        --max-context "$CTX" --kv-capacity "$KV_CAP" --max-concurrency "$CONC" \
        --kv-dtype int8 --prefill-chunk 2048 --pending-timeout-ms 600000 \
        --spec mtp --draft-tokens 3 --lm-head-draft --preserve-thinking --cors
    for i in $(seq 1 40); do
      [ "$(curl -s -o /dev/null -w '%{http_code}' "http://127.0.0.1:${PORT}/health" || true)" = 200 ] \
        && { echo "就绪: http://127.0.0.1:${PORT}/v1  (model id: qwen3.8-27b)"; exit 0; }
      sleep 5
    done
    echo "未就绪,看日志: docker logs ninfer"; exit 1
    

    开机自启:容器带 --restart unless-stopped 即可;功率墙用上面那个脚本挂一个 oneshot 单元:

    # /etc/systemd/system/nvidia-powerlimit.service
    [Unit]
    Description=Lock V100 power limit
    After=systemd-modules-load.service
    Before=docker.service
    [Service]
    Type=oneshot
    RemainAfterExit=yes
    ExecStart=/usr/local/bin/nvidia-powerlimit.sh 200
    [Install]
    WantedBy=multi-user.target
    
    1 条回复 最后回复
    1
    • D
      D
      davidwei0826
      体面乡绅
      编写于 最后由 davidwei0826 编辑
      #2

      整个kv在nvfp4的方案里最多只有256k.在单并发长上下文和双并发短上下文中,选择了后者。 Prefill在高上下文时衰减比较严重,均衡选择了c=2, ctx=128k。
      V100这两天开始涨价了。 纯文字llm,不做视频的,可以参考。

      1 条回复 最后回复
      0

      你好!看起来您对这段对话很感兴趣,但您还没有一个账号。

      厌倦了每次访问都刷到同样的帖子?您注册账号后,您下次访问时都将自动回到上次浏览的位置,并可选择接收新回复的通知(通过电子邮件或推送通知)。您还可以收藏帖子、为帖子点赞,以此向其他社区成员表达您的感谢。

      有了你的建议,这篇帖子会更精彩哦 💗

      注册 登录
      回复
      • 在新帖中回复
      登录后回复
      • 从旧到新
      • 从新到旧
      • 最多赞同


      • 登录

      • 登录或注册以进行搜索。
      • 第一个帖子
        最后一个帖子
      0
      • 版块
      • 最新
      • 标签
      • 热门
      • 用户
      • 群组