KaiWuBOSS
V2EX  ›  Local LLM

我做了个工具让 8GB 显卡跑 30B 模型从 3 tok/s 提到 21 tok/s,记录一下技术发现

  •  1
     
  •   KaiWuBOSS · Apr 24 · 10922 views
    This topic created in 62 days ago, the information mentioned may be changed or developed.

    最近在折腾本地大模型,发现一个核心问题:Ollama 和 LM Studio 能让模型跑起来,但参数全靠猜——上下文长度、KV cache 类型、MoE expert 放哪、ubatch 多大……用默认参数基本是在浪费显卡。

    于是做了个工具自动找最优配置,过程中踩了不少坑,记录一下。


    核心发现

    1. MoE 模型的 offload 策略决定了一切

    Qwen3-30B-A3B 是 MoE 架构,在 8GB 显卡上:

    • LM Studio 默认把所有层塞进显存 → 7549MB ( 93%),3 tok/s
    • 只把 attention 层放 GPU ,MoE expert 层走 CPU → 2603MB ( 32%),21 tok/s

    快了 7 倍,显存反而省了 65%。关键是 llama.cpp 支持这个,但你得自己识别哪些 tensor 是 MoE expert (.ffn_.*_exps. 这类命名),然后手动配。

    2. KV cache 类型影响比大多数人想的大

    同一张 8GB 显卡跑 Llama 3.1 8B ,不同 KV cache 配置速度差异:

    配置 ctx 速度
    iso3+iso3 ,4 slot 8K 19.4 tok/s
    q8_0+q4_0 ,1 slot 8K 38.2 tok/s
    f16+f16 ,1 slot 8K 51.7 tok/s
    f16+f16 ,1 slot (自动) 64K 26.2 tok/s

    f16 比 iso3 快将近 3 倍。但 f16 显存占用更大,所以正确策略是:先算 f16 KV cache 占多少显存,装得下就用 f16 ,装不下再降级。

    公式:KV_MB = 2 × layers × kv_heads × head_dim × ctx × bytes / 1024²

    3. oobabooga 公式用来预测 ctx 上限

    社区里流传的 oobabooga 显存估算公式,原本用来预测装载模型后剩余显存能支持多大 ctx 。但这个公式是基于 q8_0/f16 拟合的,用 iso3 的时候会严重高估显存需求,导致 ctx 只算出 4K 。

    最后放弃公式预测,改成二分探测:从 min(nativeCtx, 65536) 开始,OOM 就减半,最多探 5 次,让 llama-server 自己告诉我能跑多少。Llama 3.1 8B 的 ctx 从 4K 直接到 64K 。

    4. parallel slot 数量对单用户场景影响巨大

    llama.cpp 默认开 4 个并行 slot (为了多用户并发),但单用户场景下这会把 VRAM 分成 4 份。

    关掉多余 slot (--parallel 1)之后:18.5 → 38.2 tok/s ,直接翻倍。

    5. ubatch 实测比理论更可靠

    ubatch 128 vs 512 的性能差异跟模型和显卡都有关系,没有通用最优值。实测结论:

    • 8K ctx:ubatch 512 比 128 快 7.6%
    • 64K ctx:ubatch 512 比 128 快 21.6%

    直接 benchmark 两个值取快的,比查文档猜靠谱。

    6. 对话压缩不要用模型生成摘要

    最初方案是上下文满了之后调本地模型生成摘要——结果单 slot 阻塞,直接超时。

    改成纯算法提取:保留头部( system prompt + 首轮对话)和尾部(最近 8K tokens ),中间部分提取代码路径、函数名、文件名、TODO 等关键信息。压缩率 73%,耗时 <1ms 。


    用了哪些技术,实现了什么功能

    llama.cpp — 推理引擎核心

    直接调用 llama.cpp 的 llama-server ,所有参数( ctx 、KV cache 类型、线程数、ubatch 、mlock 、tensor split )都通过启动参数注入。Kaiwu 本质上是一个参数决策层,不改推理引擎本身。

    IsoQuant / TurboQuant — 3-bit KV cache 压缩

    集成了 johndpope 的 turboquant fork (feature/planarquant-kv-cache),支持 -ctk iso3 -ctv iso3 参数。iso3 的压缩系数实测 0.73 ,理论值 0.75 ,在 VRAM 紧张的设备( 8GB )上可以把 KV cache 占用压缩到 q8_0 的一半。但有约 600MB 固定解码 buffer 开销,VRAM 充裕时反而比 f16 慢 8%,所以策略是 VRAM > 16GB 才默认开 iso3 。

    oobabooga 显存估算公式 — ctx 上限预测(已放弃)

    社区流传的公式用来预测剩余显存能支持多大 ctx ,基于 q8_0/f16 拟合。iso3 场景下高估显存需求,导致 ctx 只算出 4K 。最终改成二分探测代替公式,让 llama-server 自己决定能跑多少。

    GQA 架构识别 — KV cache 精准估算

    Qwen3 等新模型用 GQA ( Grouped Query Attention ),kv_heads 远小于 attention_heads 。KV cache 大小公式里用的是 kv_heads 而不是 heads ,不识别这一点会高估 3-4 倍。通过读 GGUF metadata 拿到准确的 kv_heads 值再做计算。

    MoE tensor 识别 — 自动 expert offload

    读取模型的 tensor 名称列表,匹配 .ffn_.*_exps. 模式识别出 MoE expert 层,自动决定把这部分路由到 CPU 。不需要用户手动指定,也不需要提前知道模型架构。

    Extractive Summary — 零延迟对话压缩

    上下文到 75% 时触发,纯算法提取:保留 system prompt 、首轮对话、最近 8K tokens ,中间部分按关键词权重保留(代码路径、函数名、文件名、TODO 、命令行等)。不调用任何模型,压缩耗时 <1ms ,73% 压缩率。最初试过调本地模型生成摘要,单 slot 阻塞直接超时,这条路走不通。

    GitHub Actions CI — 跨平台自动编译

    turboquant fork 需要自己编译带 iso3 支持的 llama-server 。用 GitHub Actions 同时编译 Windows ( MSVC )和 Linux ( GCC )版本,CUDA 12.4 ,覆盖 sm_75/80/86/89 架构,RTX 50 系列通过 PTX JIT 运行时支持。踩了三个 MSVC 编译坑( extern "C" 声明改定义、M_PI 未定义、全局符号缺失),记录在 PROGRESS.md 里。


    工具

    把上面这些逻辑都自动化了,叫开物( Kaiwu )。一行命令启动,参数全部自动找,结果缓存起来,第二次 2 秒启动。

    GitHub: https://github.com/val1813/kaiwu

    OpenAI 兼容 API ,Continue / Cursor / Claude Code 直接接。


    有遇到类似问题的欢迎交流,尤其是 MoE offload 和 KV cache 这块踩坑挺深的。

    Supplement 1  ·  Apr 25
    上线一天 感谢大家试用 我们加紧优化了 8 个版本
    从 v0.1.1 到 v0.1.8 ,Kaiwu 解决的核心问题可以分三类:

    让模型真正跑起来(稳定性)
    v0.1.1 发布时,iso3 KV cache 检测时机有 bug——warmup 用 iso3 参数启动 llama-server ,但还没确认 binary 支不支持,导致所有 ctx 探测失败、误报 OOM ( v0.1.2 修)。Blackwell 架构( RTX 50 系)的 iso3 检测超时只有 10 秒,但 SM120 首次启动需要 PTX JIT 编译约 30 秒,直接超时失败( v0.1.4 修)。MoE offload 的 -ot 正则路由 expert 层到 CPU 实际没生效,所有层都上 GPU ,8GB 装不下 13GB 模型( v0.1.6 修,改用 --cpu-moe )。kaiwu run /path/to/model.gguf 传绝对路径时实际走下载流程而不是用本地文件( v0.1.6 修)。

    让 warmup 找到真正最优的配置(调参质量)
    iso3 每次启动都重新检测,RTX 50 系每次要等 30 秒( v0.1.5 加磁盘缓存)。小模型(<2GB ) ubatch 用 512 导致--kv-unified 预分配 OOM ( v0.1.5 修,降到 128 )。MoE offload 的 KV cache 选择用全量模型大小估算 GPU 占用,算出来是负数,导致 warmup 全 OOM ( v0.1.6 修,信任 --fit on 处理层分配)。MoE warmup 超时只有 60 秒,13GB 模型从内存加载来不及( v0.1.6 延长到 180 秒)。MoE warmup 用 18 tok/s 阈值,但 PCIe 带宽限制下 MoE 最多 13-15tok/s ,阈值永远达不到,warmup 总是 fallback 到最小 ctx ( v0.1.7 改 8 ,v0.1.8 直接去掉阈值——MoE 速度跟 ctx 无关,找最大能跑的 ctx 就行)。

    让更多客户端能用(兼容性)
    新版 Cursor 和 Claude Code 调用 /responses (不带 /v1/ 前缀),proxy 只注册了 /v1/responses ,返回 404 ( v0.1.7 修)。发布包没有打包 OpenSSL DLL ,用户需要手动装 OpenSSL 才能跑 llama-server ( v0.1.6 CI 改动,自动打包)。

    再次感谢各位热心指导 如有问题随时反馈 我尽快优化
    107 replies    2026-05-06 08:25:40 +08:00
    1  2  
    KaiWuBOSS
        101
    KaiWuBOSS  
    OP
       Apr 28   ❤️ 1
    @kevan 现有版本支持 50 了 你能不能试试 我努力好久了
    kevan
        102
    kevan  
       Apr 28 via Android
    @KaiWuBOSS 下班回家马上试用反馈,我跟进了好久,哈哈哈,必须支持
    xuhengjs
        103
    xuhengjs  
       Apr 29
    有没有跑 qwen3.6-35B-A3b 的案例看看
    nanshan2012
        104
    nanshan2012  
       Apr 30
    @KaiWuBOSS 使用 V0.26 版本是正常的,使用 V0.31 版本就出现报错了,请大神看看

    本地大模型部署器 vv0.3.1 · llama.cpp b8864
    by llmbbs.ai · 本地 AI 技术社区

    [1/6] Probing hardware...
    GPU: NVIDIA GeForce RTX 4060 Laptop GPU (SM89, 8188 MB VRAM, 272 GB/s)
    RAM: 95 GB DDR5
    OS: windows amd64

    [2/6] Selecting configuration...
    Model: Qwen3.6-35B-A3B (moe, 38B total / 1B active)
    Quant: Q4_K_M (20.6 GB)
    Mode: moe_partial
    Accel: Flash Attention + SWA-Full (hybrid arch)

    [3/6] Checking files...
    Using bundled iso3 binary: llama-server-cuda.exe
    Binary: llama-server-cuda.exe [cached]
    Model: Qwen3.6-35B-A3B-UD-Q4_K_M.gguf [cached]

    [4/6] Preflight check...
    ✓ VRAM sufficient

    [5/6] Warmup benchmark...
    旧缓存格式,重新探测
    Probe 1: ctx=256K ... OOM
    Probe 2: ctx=128K ... OOM
    Probe 3: ctx=64K ... OOM
    Probe 4: ctx=32K ... OOM
    Probe 5: ctx=16K ... OOM
    Probe 6: ctx=8K ... OOM
    ⚠️ Warmup failed: all ctx probes failed (tried down to 4K)
    Using default parameters

    [6/6] Starting server...
    Waiting for llama-server to be ready (port 11434)...
    ⚠️ 显存不足,降低上下文至 4K 重试...
    Waiting for llama-server to be ready (port 11434)...
    Error: failed to start llama-server: 连续 2 次启动失败,即使最小上下文(4K)也无法运行

    NVIDIA GeForce RTX 4060 Laptop GPU: 8188 MB VRAM
    模型 Qwen3.6-35B-A3B: ~21104 MB
    KV cache (4K, q4_0): ~80 MB
    预估总需: ~22208 MB

    差额: 14020 MB

    建议:
    1. 选择更小的量化 (Q4_K_M 或 Q2_K)
    2. 选择更小的模型

    Usage:
    kaiwu run <model> [flags]

    Flags:
    --bench Run benchmark after starting
    --ctx-size int 手动指定上下文大小( 0=自动)
    --fast Skip warmup, use cached profile
    -h, --help help for run
    --host string 监听地址(默认 127.0.0.1 ,用 0.0.0.0 开放局域网) (default "127.0.0.1")
    --llama-server string 使用自定义 llama-server 二进制(完整路径)
    --mode string 模式选择: speed/balanced/context (默认用上次选择)
    --reset 清除缓存,重新 warmup 探测最优参数
    tubanwu
        105
    tubanwu  
       Apr 30
    @KaiWuBOSS 跑不起来
    本地大模型部署器 vv0.3.1 · llama.cpp b8864
    by llmbbs.ai · 本地 AI 技术社区

    [1/6] Probing hardware...
    GPU: NVIDIA GeForce RTX 5060 (SM120, 8151 MB VRAM, 448 GB/s)
    RAM: 31 GB DDR4
    OS: windows amd64
    ⚠️ CUDA 13.2 detected — known bug with low-bit quantization
    If you see garbled output, downgrade driver to CUDA 13.1
    Warning: RTX 50 series with CUDA 13.2 detected
    Kaiwu will use CUDA 12.4 binary for stability.

    [2/6] Selecting configuration...
    Model: Qwen3.6 35B A3B Claude 4.7 Opus Reasoning Distilled (moe, 22B total / 1B active)
    Quant: Q22 (13.5 GB)
    Mode: moe_partial
    Accel: Flash Attention + SWA-Full (hybrid arch)

    [3/6] Checking files...
    Using bundled iso3 binary: llama-server-cuda.exe
    Binary: llama-server-cuda.exe [cached]
    Model: Qwen3.6-35B-A3B-Claude-4.7-Opus-Reasoning-Distilled.i1-IQ3_XS.gguf [cached]

    [4/6] Preflight check...
    ✓ VRAM sufficient

    [5/6] Warmup benchmark...
    RTX 50 系首次运行,正在编译 CUDA 内核(约 60s ,仅需一次)...
    ✓ CUDA 内核编译完成,后续启动将秒开
    ⚠ JIT 预热失败: exit status 0xc0000135
    Probe 1: ctx=128K ... OOM
    Probe 2: ctx=64K ... OOM
    Probe 3: ctx=32K ... OOM
    Probe 4: ctx=16K ... OOM
    Probe 5: ctx=8K ... OOM
    ⚠️ Warmup failed: all ctx probes failed (tried down to 4K)
    Using default parameters

    [6/6] Starting server...
    Waiting for llama-server to be ready (port 11434)...
    ⚠️ 显存不足,降低上下文至 4K 重试...
    Waiting for llama-server to be ready (port 11434)...
    Error: failed to start llama-server: 连续 2 次启动失败,即使最小上下文(4K)也无法运行

    NVIDIA GeForce RTX 5060: 8151 MB VRAM
    模型 Qwen3.6 35B A3B Claude 4.7 Opus Reasoning Distilled: ~13813 MB
    KV cache (4K, q4_0): ~80 MB
    预估总需: ~14917 MB

    差额: 6766 MB

    建议:
    1. 选择更小的量化 (Q4_K_M 或 Q2_K)
    2. 选择更小的模型

    Usage:
    kaiwu run <model> [flags]

    Flags:
    --bench Run benchmark after starting
    --ctx-size int 手动指定上下文大小( 0=自动)
    --fast Skip warmup, use cached profile
    -h, --help help for run
    --host string 监听地址(默认 127.0.0.1 ,用 0.0.0.0 开放局域网) (default "127.0.0.1")
    --llama-server string 使用自定义 llama-server 二进制(完整路径)
    --mode string 模式选择: speed/balanced/context (默认用上次选择)
    --reset 清除缓存,重新 warmup 探测最优参数
    jiaorong
        106
    jiaorong  
       May 1
    支持 vulkan 的技术吗?
    kevan
        107
    kevan  
       May 6 via Android
    还是用不了
    1  2  
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   4707 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 45ms · UTC 09:47 · PVG 17:47 · LAX 02:47 · JFK 05:47
    ♥ Do have faith in what you're doing.