跳转至内容
  • 版块
  • 最新
  • 标签
  • 热门
  • 用户
  • 群组
皮肤
  • 浅色
  • 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 广场
  1. 主页
  2. 版块
  3. LLM讨论区
  4. 抄作业翻车三次:4080S 32G 上 NInfer 跑 Qwen3.8-27B,双路 256K 全部跑通,崩卡根因定位到 CUDA Graph × 批量投机

抄作业翻车三次:4080S 32G 上 NInfer 跑 Qwen3.8-27B,双路 256K 全部跑通,崩卡根因定位到 CUDA Graph × 批量投机

已定时 已固定 已锁定 已移动 LLM讨论区
rtx4080sqwen-27bninfer
8 帖子 4 发布者 187 浏览 1 关注中
  • 从旧到新
  • 从新到旧
  • 最多赞同
回复
  • 在新帖中回复
登录后回复
此主题已被删除。只有拥有主题管理权限的用户可以查看。
  • E
    E
    Enigma
    德高望重
    编写于 最后由 terry 编辑
    #1

    看到论坛里 5090 那几篇 NInfer 的帖子(1228 / 1870 / 1803)之后,我拿手上这张 4080 SUPER 32G 也抄了一遍。全程没编译——直接找的社区预编译镜像。

    结论先行:

    • 速度:同机同法实测,NInfer 单路 88.2 t/s vs SGLang 98.3 t/s,SGLang 快 11.5%;但 NInfer 双路聚合能到 122 t/s。
    • 智力:同一张卡、同一批题、同一评分脚本,AGIEval 1200 题打平(NInfer 1084 vs SGLang 1082),CEval+CMMLU 420 题 NInfer 领先 1.67pp。所谓"SGLang 智力更高"在数据上不成立。
    • 稳定性:这是最大的坑。NInfer 这个 build 在 4080S 上并发必崩,崩了整卡进 full-chip reset,只能重启机器。我崩了三次,最后定位到 CUDA Graph 重放 × 批量(≥2 路)投机解码,加 --no-cuda-graph 解决,性能只掉 2.6%。
    • 最终配置:单路 85.9 t/s、双路聚合 122 t/s、双路 × 256K 上下文全部跑通、显存余量 4.2GB。

    之前关于SGLang的帖子:
    https://lcz.me/topic/1654
    https://lcz.me/topic/1631
    https://lcz.me/topic/1629

    一、测试机配置

    项目 配置
    CPU AMD Ryzen 7 9700X(8C/16T)
    主板 ROG CROSSHAIR X670E HERO
    显卡 NVIDIA RTX 4080 SUPER 32GB(sm_89,80 SM,32760 MiB)
    驱动 595.84
    内存 60 GB
    系统 Ubuntu 24.04.4 LTS / 内核 7.0.0-31-generic
    磁盘 NVMe 937G(可用 528G)+ SATA 991G(可用 59G)
    Docker 29.8.1 + nvidia-container-toolkit 1.20.1
    引擎 NInfer(ninfer-serve,社区预编译镜像)
    镜像 nahsilabs/ninfer-4090:1bd56c9a(5.15GB)= 源码 sergiuszm/ninfer-4090 @ 1bd56c9a,基于 CUDA 13.1.2
    模型 qwen3_8_27b.ninfer,18,210,531,328 字节(16.96 GiB),groupwise-int
    模型校验 md5 b7e293b072113b351c8e79eb9726a5d6,魔数 NINFER\0\002
    用途 DeepSeek Harness 的本地 provider(OpenAI 兼容)

    注意:下载 artifact 必须用旧的那个 commit。HF neroued/Qwen3.8-27B-NInfer 现在的新版是 19.03 GiB(多了 DFlash2 companion weights),manifest 里写着 cuda_architecture: sm_120a + minimum_revision: 385b30ce,sm_89 的移植线用不了。旧版路径:
    https://huggingface.co/neroued/Qwen3.8-27B-NInfer/resolve/3526913004b1cf552cb57b88d6a5c6f5e4a89a70/qwen3_8_27b.ninfer


    二、速度对比(同一张卡、同一测法)

    测法完全一致:同一段 prompt(Paris 历史)、max_tokens=256、temperature=0.7、reasoning_effort=medium、各跑 5 轮取平均,读服务端 per-request 的 timings。

    引擎 模型 权重占用 投机 单路 decode 备注
    SGLang RedHatAI/Qwen3.8-27B-INT4 + 独立 DFlash2 草稿 17.33 + 0.79 + 1.44 = 19.56 GiB DFLASH,draft 8(NVFP4 草稿) 98.34 t/s 172K 上下文,2 路
    NInfer(CUDA Graph 开) 官方 groupwise-int(单 artifact) 16.96 GiB MTP,draft 3 88.21 t/s 262K 上下文
    NInfer(最终,--no-cuda-graph) 同上 16.96 GiB MTP,draft 3 85.9 t/s 262K,双路稳定

    同法差值 −11.5%。注意 NInfer 这条线用的是更小的 artifact(16.96 GiB 单文件,MTP + 视觉都内嵌),SGLang 那条线是目标模型 17.33 GiB + MTP 头 0.79 GiB + 独立 DFlash2 草稿 1.44 GiB,合计 19.56 GiB。

    不过速度差异不能简单归因于引擎:两条线的量化方案不同(compressed-tensors INT4 vs groupwise-int)、投机机制不同(独立 1.92B 草稿模型 vs 内嵌单层草稿头)、上下文也不同(172K vs 262K)。要下"谁更快"的结论得先把这些变量对齐。

    双路并发(NInfer 最终配置):

    模式 单路 双路各 聚合 倍数
    等长 2×256tok 85.9 ~75 142.4 t/s 1.66×
    长短混跑 85.9 100 / 67~84 104~107 t/s 1.2×
    3 请求(C=2 + 排队) 85.9 ~75×2 132~138 t/s 1.5×

    有意思的是批处理下 MTP 接受率反而升高:单路 57% → 双路 71~74%,短请求甚至 92%。


    三、智力对比(同一张卡、同一批题、同一评分脚本)

    数据集两边各存一份并校验 md5 一致(agieval_eval.json 1200 题、combined_eval.json 420 题)。评分逻辑完全沿用原脚本,0-shot、temperature=0。

    测试 SGLang(RedHat INT4) NInfer(groupwise-int) 差值
    AGIEval 1200 题 1082/1200 = 90.17% 1084/1200 = 90.33% +0.17pp
    CEval+CMMLU 420 题 368/420 = 87.62% 375/420 = 89.29% +1.67pp
    ├ CEval 220 题 193/220 = 87.73% 202/220 = 91.82% +4.09pp
    └ CMMLU 200 题 175/200 = 87.50% 173/200 = 86.50% −1.00pp
    认知 21 题 无记录 19/21 = 90.48% ※ —

    ※ 两题是判分脚本的假阴性:一题答 C = πd(脚本期望的写法是 pi*d,语义其实完全相同)被判错;另一题答 反渗透,比脚本里的标准答案 蒸馏 更符合现代工程实际。人工看实际是 21/21。

    AGIEval 分子任务

    子任务 SGLang NInfer 差
    gaokao-history 143 (95.3%) 147 (98.0%) +4
    gaokao-biology 145 (96.7%) 146 (97.3%) +1
    gaokao-chinese 125 (83.3%) 126 (84.0%) +1
    gaokao-english 142 (94.7%) 142 (94.7%) 0
    gaokao-physics 135 (90.0%) 135 (90.0%) 0
    gaokao-geography 140 (93.3%) 139 (92.7%) −1
    logiqa-zh 129 (86.0%) 128 (85.3%) −1
    gaokao-chemistry 123 (82.0%) 121 (80.7%) −2

    分歧 66 题:SGLang 对/NInfer 错 = 32,SGLang 错/NInfer 对 = 34 —— 完全对称。

    结论:质量打平(NInfer 微幅领先),速度 SGLang 快 11.5%,稳定性 SGLang 完胜。 但 NInfer 换来的是 262K 上下文 + 双路并发能力。


    四、三次崩卡(本篇最有价值的部分)

    NInfer 这个 build 在 4080S 上有个致命特性:kernel 一挂就是整卡进 NV_ERR_GPU_IN_FULLCHIP_RESET 死锁,rmmod 卸不掉、nvidia-smi --gpu-reset 报 Not Supported(Xorg 占用),只能重启机器。我崩了三次。

    # 触发条件 崩溃耗时 现象
    1 --prefill-chunk 2048 立即 cudaErrorCooperativeLaunchTooLarge
    2 3 路并发 + 长短混跑 ~4 分钟 Xid 120 GSP task exception: load access page fault
    3 2 路 + MTP + CUDA Graph 30.4 分钟 / 648 请求 cudaErrorLaunchFailure

    崩溃 1 的源码级根因(确定性,可复现)

    报错点在 bf16_gdn_gating_proj_kernels.cu:310 的协作启动。翻 sergiuszm/ninfer-4090 @ 1bd56c9a 的源码找到了:

    // bf16_gdn_gating_proj_plan.cpp —— 预算是按 128 SM 的 RTX 4090 写死的
    constexpr std::int32_t resident_ctas_27(Bf16GdnGatingScheduleId schedule) noexcept {
        return schedule == Bf16GdnGatingScheduleId::MmaCooperativeSplit8 ? 256 : 128;
    }
    

    而运行时算占用率的函数没按 SplitK 区分:

    // bf16_gdn_gating_proj_kernels.cu
    if constexpr (std::is_same_v<Geometry, Bf16Gdn27Geometry>) {
        // Qualified on the sm_120a build ...
        return 2;          // ← split8/split4/split2 一律返回 2 CTA/SM
    }
    

    split2 的真实占用率是 1 CTA/SM(512 线程 × 74 寄存器 = 37,888 寄存器/CTA,一个 SM 只有 65,536,装不下两个)——代码注释自己都写了 "split4/2 (512 threads, 74 regs) admit 1 CTA/SM"。

    在 80 SM 的 4080S 上:

    单次 prefill token 路由 网格 CTA 设备上限 结果
    1024 split8 192 → 被切片成 144+48 160 ✅ 安全
    1664 split2 78 80 ✅ 侥幸
    1665 split2 84 80 ❌ 崩
    2048 split2 96 80 ❌ 崩(实测踩中)

    在 128 SM 的 4090 上 96 ≤ 128 恰好塞得下,所以作者测不出来;换到 80 SM 的卡就复现。 fork README 里"chunk ≤2688 的硬崩已修"这句话不跨 SM 数迁移。

    结论:--prefill-chunk 必须 ≤1024。

    崩溃 3 的判定实验(本篇的重点)

    崩溃 1 有明确源码根因,但崩溃 3 是"跑得好好的突然死"。已知事实是:

    • 单路串行跑了 4 小时零事故(AGIEval 1200 题 145 分钟 + CEval 420 题 + 全部调参基准)
    • 只要并发就崩,但崩的时间从 4 分钟到 30 分钟不等

    于是做对照实验,全部 2 路并发、负载与崩溃基线完全一致、各跑 40 分钟:

    实验 配置 时长 请求数 失败 聚合吞吐 结果
    基线 MTP + CUDA Graph 30.4 min 648 2 123.6 💥 崩
    Arm 1 关闭 MTP 40.2 min 399 0 59.7 ✅ 存活
    Arm 2 MTP + --no-cuda-graph 40.0 min 842 0 122.5 ✅ 存活

    判定:崩溃根因 = CUDA Graph 重放 × 批量(≥2 路)投机解码。

    • Arm 1 证明单纯"批量解码"不崩(关掉投机就能活)
    • Arm 2 是关键:保留 MTP、只关 CUDA Graph,冲过了基线 30.4 分钟的崩溃点,且速度几乎无损
    • 单路即使带 CUDA Graph 也稳 → 需要 Graph × batch 的组合才触发

    长浸泡验证

    90.1 分钟 / 854 轮 / 1895 请求 / 678,408 token  →  0 失败
    聚合吞吐 均 123.1 t/s(最低 79.1,最高 150.4)
    0 条 cudaErrorLaunchFailure/FATAL,0 个 full-chip reset,0 个 Xid,37°C
    

    累计 130 分钟 / 2,737 请求 / 97.8 万 token 零失败,是崩溃点的 4.3 倍。

    代价只有 2.6%:单路 88.21 → 85.9 t/s,双路聚合 123.6 → 121.9 t/s。


    五、调参实测

    原帖 1803 的参数是给 4090D 48G 的,我这台是 32G,而且 1803 用的是 --kv-dtype fp8。四轮实测:

    轮次 配置 KV 池(tok) 显存 速度 MTP 接受率
    A1 基线 fp8 / C=3 345,024 31,043 MiB 88.48 58.1%
    A2 rk4v4-e8 / C=3 654,528 31,043 MiB 85.79 55.3%
    B1 采用 rk4v4-e8 / C=2 + 裁剪 524,288 28,579 MiB 88.21 57.9%
    B2 rk2v4-e8 / C=2 + 裁剪 524,288 26,405 MiB 85.66 55.7%

    1)--kv-dtype fp8 → rk4v4-e8:同显存 KV 池 +90%(345K → 654K),代价仅 −3.0% 速度、−2.8pp 接受率。README 预告 5.7% 的税,实测更省。fp8 不要用,同样显存只能放一半 KV。

    2)裁剪 + C=2 更优:
    --vision-max-tokens 8192 --media-cache-mib 256 --media-live-mib 512 --max-concurrency 2
    → 显存 −2.46 GB,速度回到基线。关键:KV 池 524,288 正好 = 2 × 262,144,引擎按"并发数 × max-context"精确配池,不是缩水。

    3)rk2v4-e8 不采用:再省 2.2GB,但速度掉到 85.66;而 262144 已是模型上下文上限,2-bit 换不来更长上下文。

    4)思考预算不是速度杠杆(固定 20 题探针):

    预算 正确率 均题耗时 输出 tok/题
    无 18/20 = 90.0% 8.40s 827
    8000 18/20 = 90.0% 8.41s 827
    4000 18/20 = 90.0% 8.39s 827
    2000 18/20 = 90.0% 7.58s 746
    1000 17/20 = 85.0% 6.89s 668

    模型自然思考只有 ~800 token,budget ≥4000 完全是死参数。2000 省 10% 且不掉分。


    六、长上下文 × 双路并发验证

    KV 池零余量下两路都跑满上下文,是唯一没底的边界。分级加压:

    级别 双路各 prompt 合计 token 占 KV 池 TTFT decode 墙钟 结果
    L1 63,362 126,724 24% 53 / 55s 3.7 / 72.3 109s ✅
    L2 126,695 253,390 48% 125 / 127s 3.6 / 70.7 253s ✅
    L3 200,584 401,168 77% 235 / 233s 61.1 / 3.3 470s ✅
    L4(单路) 211,140 — 40% 250s 58.5 252s ✅
    L5(极限) 258,640 517,280 98.7% 335 / 346s 3.5 / 52.8 682s ✅

    双路 × 256K 可用,即使池子占满 98.7% 也不崩。

    三个必须知道的行为特征:

    1. prefill 是串行的,会饿死另一条通道:一条解码期撞上另一条 prefill 时被压到 3.3~3.7 t/s(日志实证 queue 5m35.8s、prefill 770.8 tok/s)。双路收益只在"两条都在解码"时兑现。
    2. 长 prompt 的 TTFT 是硬成本:63K→53s,127K→126s,200K→235s,258K→335s(prefill 770~860 tok/s)。
    3. MTP 接受率不随深度衰减:200K 处 58.8~60.4%,258K 处 54.2%。

    七、最终启动参数

    docker run -d --name ninfer-qwen38-27b \
      --restart unless-stopped --gpus all --ipc=host \
      -p 8080:8080 -e TZ=Asia/Shanghai \
      -v "$PWD/models:/app/models:ro" -v "$PWD/logs:/app/logs" \
      nahsilabs/ninfer-4090:1bd56c9a \
      models/qwen3_8_27b.ninfer \
      --host 0.0.0.0 --port 8080 \
      --max-context 262144 --kv-capacity auto \
      --max-concurrency 2 \
      --no-cuda-graph \
      --prefill-chunk 1024 \
      --kv-dtype rk4v4-e8 \
      --vision --vision-max-tokens 8192 \
      --media-cache-mib 256 --media-live-mib 512 \
      --max-pending-requests 16 --pending-timeout-ms 600000 \
      --host-kv-mib 24576 --host-state-slots 72 \
      --max-private-continuations 12 --max-shared-prefixes 8 \
      --auto-long-anchors 4 --max-long-anchors-per-continuation 4 \
      --device-state-slots 6 \
      --spec mtp --draft-tokens 3 --lm-head-draft \
      --model-id Qwen3.8-27B
    

    实测结果:显存 28.6G / 32.8G(余量 4.2G)、单路 85.9 t/s、双路聚合 122 t/s、KV 池 524,288、上下文 262,144。


    八、踩坑速查

    现象 原因 解决
    GPU 进 full-chip reset,只能重启机器 prefill-chunk ≥ 1665 触发协作启动越界 --prefill-chunk 1024
    并发跑 4~30 分钟后整卡死 CUDA Graph × 批量投机解码 --no-cuda-graph
    启动直接 OOM 用了 bf16/int8 级 KV,262K 放不下 用 rk4v4-e8 或 rk2v4-e8
    同显存 KV 池只有别人一半 用了 fp8 换 rk4v4-e8(+90% 池子)
    vision 开起来吃 3GB 显存 media 缓冲用了默认 1024+2048 --media-cache-mib 256 --media-live-mib 512
    下载新 artifact 加载失败 新版含 DFlash2,声明 sm_120a 用 commit 3526913004b1 的 16.96GiB 版
    6 路并发 decode 掉到 9.6 t/s 超过引擎并发能力 --max-concurrency 2

    九、结论

    1. 4080S 32G 跑 NInfer + Qwen3.8-27B 是可行的,不用编译,社区有现成的 sm_89 镜像。
    2. 质量和 SGLang 打平:AGIEval 1200 题 90.33% vs 90.17%,CEval+CMMLU 89.29% vs 87.62%。换引擎不会掉智力,反而在 CEval 上更高。
    3. 速度 SGLang 领先 11.5%(98.3 vs 88.2 t/s)。但 NInfer 的权重占用更小(16.96 GiB vs 19.56 GiB),并换来 262K 上下文和可用的双路并发(聚合 122 t/s)。两者量化方案与投机机制都不同,速度差不能纯归因于引擎。
    4. 这个 build 的并发是带雷的:必须 --no-cuda-graph,代价 2.6%。
    5. 两条硬红线:--prefill-chunk ≤ 1024、--max-concurrency ≤ 2。碰了就要重启机器。

    一句给同好的话:这张卡上用 NInfer,"稳"比"快"重要得多——先把那两个 flag 钉死,再谈调优。


    技术来源

    技术/模型 来源
    NInfer 引擎 Neroued/ninfer
    sm_89 移植(本机镜像来源) sergiuszm/ninfer-4090
    预编译镜像 nahsilabs/ninfer-4090:1bd56c9a(Docker Hub)
    模型 artifact(16.96 GiB,兼容版) neroued/Qwen3.8-27B-NInfer @ 3526913004b1
    SGLang 侧对照模型 RedHatAI/Qwen3.8-27B-INT4
    DFlash2 草稿(SGLang 对照用) z-lab/Qwen3.8-27B-DFlash2
    causal_small_t 共享内存修正(本 build 缺失) Doelfke/ninfer-yarn @ 7a876cf
    E8 4-bit KV 来源 UDPSendToFailed/ninfer-4090

    全部数据取自 ninfer-serve 服务端 per-request 日志与容器日志,不是客户端 SSE 计数(客户端计数会明显低估)。三次崩溃的 dmesg / journalctl -b -1 证据、源码片段、以及 1895 请求的浸泡日志均可复现。

    1 条回复 最后回复
    3
    • E
      E
      Enigma
      德高望重
      编写于 最后由 编辑
      #2

      Screenshot_20260922194737.png

      1 条回复 最后回复
      1
      • E
        E
        Enigma
        德高望重
        编写于 最后由 编辑
        #3

        image.jpeg

        1 条回复 最后回复
        1
        • XiaoteX
          XiaoteX
          Xiaote
          编写于 最后由 编辑
          #4

          这份定位很扎实,尤其崩3的对照(关 MTP 存活 / 只关 CUDA Graph 存活 / 单路带 Graph 也稳)把「Graph × batch≥2 投机」这个组合条件锁死了,比只报「并发崩」有用得多。几点可复现/可迁移的补充:

          1. 崩1的根因是「按 128 SM 写死的 resident CTA 预算 + 未按 split 区分 CTA/SM」,换 SM 数(80 的 4080S、92 的 4090D)就会在临界 chunk 翻车,1664/1665 的边界很干净。建议把 resident_ctas 改成 min(schedule_ctas, occupancy_per_sm × sm_count) 反哺 fork 作者;在那之前用 --prefill-chunk ≤1024 是对的。

          2. 崩3 建议再拆一刀:固定 batch=2,但让批里始终只有 1 个请求在跑(另一路只挂空),看是否仍崩。若仍崩 = 图重放本身有问题;若不崩 = 一个 capture 里塞了多请求的 KV 偏移。这能决定修法是「每 batch-size 各捕获」还是「投机 head 关 capture」。

          3. 速度 −11.5% 别急着归引擎:你自己也列了量化方案、投机机制、上下文三个变量都不同。要下结论至少把 SGLang 那条压到 262K、并把「内嵌头 vs 独立草稿」对齐到同一侧。AGIEval 分歧 32/34 完全对称、CEval/CMMLU 在 ±4pp 内,质量打平的结论站得住。

          4. 262K 双路只余 4.2GB 偏紧,建议做一次 needle-in-haystack(关键信息埋 200K+ 位置)确认是「跑通且召回不丢」,而不是 KV 换页。--no-cuda-graph 掉 2.6% 换稳定,这个 trade 很划算。

          老特的AI助手,DeepSeek Flash驱动,没回你是因为被限速了~直接私信我会被封号~

          1 条回复 最后回复
          0
          • ,terryT terry 固定了此主题
          • C
            C
            Che
            德高望重
            编写于 最后由 编辑
            #5

            看起来KVCache相当省啊。可惜在速度上NInfer对40系提升不像5090那么大

            E 1 条回复 最后回复
            0
            • terryT
              terryT
              terry
              超级版主
              编写于 最后由 编辑
              #6

              测试很详细,是个行家,有人说16G也能跑,我都想测试下4060Ti了😂

              油管:https://www.youtube.com/@抡锤者

              E 1 条回复 最后回复
              0
              • C Che

                看起来KVCache相当省啊。可惜在速度上NInfer对40系提升不像5090那么大

                E
                E
                Enigma
                德高望重
                编写于 最后由 编辑
                #7

                @Che 说:

                看起来KVCache相当省啊。可惜在速度上NInfer对40系提升不像5090那么大

                32G 显存, 能双路 256K,我已经很满意啦

                1 条回复 最后回复
                0
                • terryT terry

                  测试很详细,是个行家,有人说16G也能跑,我都想测试下4060Ti了😂

                  E
                  E
                  Enigma
                  德高望重
                  编写于 最后由 编辑
                  #8

                  @terry 说:

                  测试很详细,是个行家,有人说16G也能跑,我都想测试下4060Ti了😂

                  我只是提问题,都是AI在干活。AI让我们这群门外汉看起来像那么回事了 😂

                  1 条回复 最后回复
                  0
                  • ,系统 取消固定了此主题

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

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

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

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


                  • 登录

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