ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

V100 16GB 跑 Qwen 27B:从 4 tok/s 到 64 tok/s 的推理优化实战

V100 16GB 跑 Qwen 27B:从 4 tok/s 到 64 tok/s 的推理优化实战 先说结论这块 V100 16GB 最终把 Qwen 27B 的生成速度稳定压到了 64 tok/s从最初跑基准测试时的 4 tok/s 翻了整整 16 倍。整个过程没什么玄学全是量化格式选型、推理引擎切换、显存与带宽规划这些实打实的调整。这篇就把这次调优的完整过程摊开讲从为什么 V100 能跑 27B、量化该选哪种、引擎换谁、到最终逼近硬件的带宽极限每一步都给出我当时的选择依据和实测数据。如果你是手头只有 V100、P40、T4 这类 16GB 老卡又想跑 27B 级别模型的开发者这篇应该能帮你少走不少弯路。1. 先看清任务为什么说 V100 跑 27B 是“极限挑战”1.1 V100 的家底显存、带宽与算力在动手之前我先冷静盘了一下手头这张卡的底牌。V100 发布很多年了但它并不是“低端卡”当年就是数据中心旗舰。16GB HBM2 显存900GB/s 左右的显存带宽FP16 Tensor Core 算力约 112 TFLOPS。放到今天来看显存容量确实不够看但显存带宽放在中端卡里依然能打这才是它能跑 27B 模型的关键底牌。不过 V100 有几个硬伤后面几乎每一步优化都踩到了它不支持 BF16 的原生 Tensor Core 加速虽然部分场景可以 hmm 模拟但效率很差也没有 FP8 支持很多新出的推理 kernel 默认要求 sm_80 以上也就是 A100 那代起步V100 的 sm_70 在选型时会被一堆框架直接跳过。这意味着你不能无脑装最新版本要找到能兼容 sm_70 的那条路径。还有一个容易被忽略的点V100 16GB 是 HBM2实际有效带宽和 PCIe 传输版本也有关。如果是 PCIe 3.0 的 V100模型加载和碎片化数据传输会成为瓶颈如果是 NVLink 版卡间通信会好一些但单卡推理场景影响不大。我这张是 PCIe 版实测下来只要权重全部放显存生成阶段几乎不受 PCIe 影响瓶颈全在显存带宽。1.2 27B 模型的内存账单很多人一听说“27B 模型”第一反应是“16GB 显存怎么可能装得下”。这其实是对模型内存账本没概念。账要分开算权重、KV Cache、激活值三个大头。权重部分27B 参数如果以 FP16 存储27 × 10^9 × 2 字节 ≈ 54GBV100 根本不可能直接放进显存。但如果是 4bit 量化27 × 10^9 × 0.5 字节 ≈ 13.5GB16GB 显存刚好能塞下但余量很少。KV Cache 的大小则跟序列长度和注意力头配置强相关27B 这个体量的模型很多已经用了 GQA分组查询注意力KV Cache 相对旧模型小很多但如果你把 max_seq_len 设到 32768KV Cache 照样能吃掉好几个 GB。激活值activation在推理阶段相对可控主要是 feed-forward 层的中间结果只要设置好 batch size 和序列长度这部分一般能压在几百 MB 到 1GB 以内。我的结论是第一步必须量化量化之后还要精心规划 KV Cache 的预算否则随时可能爆显存。这也是为什么部署 27B 到 16GB 卡本质是一场“显存预算管理”的硬仗。1.3 初始 4 tok/s 是怎么来的先交代一下 4 tok/s 是怎么测出来的不然你会觉得这个起点低得离谱。我第一次部署用的是最常规的组合HuggingFace Transformers bitsandbytes 4bit 量化加载。理论上 bitsandbytes 的 4bit 加载可以把权重压到 14GB 左右模型也确实能跑起来生成速度却只有惨兮兮的 4 token 每秒。原因在推理链路。Transformers 的动态图模式会逐层执行、逐算子调度bitsandbytes 的 4bit 权重在计算时还要做反量化dequantize操作这个反量化过程本身在 V100 上并没有做专门的 kernel 优化等于每个 token 都要把所有层完整跑一遍每个算子都要经历几十微秒的低效启动开销。更麻烦的是默认的生成过程完全没有预分配显存缓存每多一个 token 都可能触发显存碎片整理一旦显存紧张就会把一部分权重临时挪到 CPU 内存那速度直接就是灾难级别。专业一点说这种方案在 V100 上的算力利用率可能连 5% 都不到。所以 4 tok/s 不是模型的极限是 Transformers 动态图 bitsandbytes 在 V100 上的调度开销被放大后的结果。想提速第一件事就是把这个推理链路整个换掉。1.4 方案选型主流推理引擎对比既然要换引擎我把当下主流的几套方案都拉出来对比了一遍前提条件都是单卡 V100 16GB、模型 27B、要求 4bit 量化、希望生成速度尽量高。方案显存友好度V100 兼容性单流生成速度潜力部署复杂度适合场景Transformers bitsandbytes中等容易 OOM兼容但 kernel 低效很低实测 4 tok/s低验证模型能否加载、做微调实验vLLM高但 4bit 支持范围有限sm_70 可用需旧版本中高但对 V100 支持有坑中高并发服务AI 应用 API 化llama.cpp GGUF高Q4_K_M 很省兼容较好CUDA 后端可用中实测约 30-45 tok/s中跨平台、CPU/GPU 混合部署ExLlamaV2 EXL2高为生成设计对 Turing/Volta 支持好高实测可到 60 tok/s中低V100 这类老卡、单流高性能推理在列这个表的时候我心里已经基本有数了ExLlamaV2 全称是 “ExLlamaV2”它的核心思路就是极致的自回归解码优化不像 Transformers 那样做通用计算图而是专门服务推理生成对量化格式的 kernel 做过深度优化而且历史上对旧显卡的兼容性一直很好。llama.cpp 是备选因为它的 GGUF 权重生态更丰富社区模型最多。提示vLLM 目前对 GPTQ、AWQ 支持很好但它的调度内核有些需要较新的计算能力。在 V100 上用旧版本 vLLM 也能跑但如果你发现启动后报 “Unsupported capabilities” 之类的错多半是版本太新需要降级到 vLLM 0.4.x 或 0.5.x 附近。最终我选了 ExLlamaV2 作为主力llama.cpp 作为模型验证和快速对比的备用工具。这个选择在后面被实测数据证明是对的同样一份 4bit 量化权重从 Transformers 换到 ExLlamaV2速度从 4 直接跳到 25 tok/s翻了 6 倍多。2. 量化选型从 54GB 压到 14GB 的取舍2.1 量化格式到底在压缩什么量化这件事的本质是把每个权重参数的存储精度降低。FP16 是 16bitINT8 是 8bit4bit 量化就是 4bit。27B 模型从 54GB 压到 13.5GB代价是每个参数从 2 字节变成 0.5 字节存储体积降到四分之一但推理时需要通过“反量化”把压缩后的权重恢复到可计算的精度这一步做得好不好直接决定了最终速度和精度。主流量化格式里GPTQ 和 AWQ 都是先对权重做分组量化再把缩放因子存起来。两者核心区别是GPTQ 以“最小化权重误差”为目标做逐层校准AWQ 则以“最小化激活值误差”为目标把注意力集中在更重要的通道上。EXL2 是 ExLlamaV2 项目自定义的格式支持混合位宽可以允许模型的不同层使用不同 bit 数从而在总文件大小不变的情况下把更多精度分配给敏感层。GGUF 则是 llama.cpp 生态的格式量化的标配是 Q4_K_M、Q5_K_M 这些它在 CPU 和 GPU 混合推理上非常强但在 V100 纯 GPU 解码时的 kernel 效率通常不如 EXL2 那么激进。2.2 为什么最终选择 EXL2我当时的测试数据很直观量化格式文件体积V100 实测生成速度精度损失粗略感受bitsandbytes 4bitNF4~14GB4 tok/s中GPTQ 4bitgroup_size128~14GB约 20-30 tok/s低AWQ 4bitgroup_size128~14GB约 20-30 tok/s低EXL2 4.25bpw~14.3GB约 25 tok/s 起低EXL2 3.75bpw~12.7GB约 50-64 tok/s中低选 EXL2 不是因为它的精度一定比 GPTQ/AWQ 好而是因为 ExLlamaV2 对 EXL2 的 kernel 优化最彻底加载、解码、缓存这些环节都是围绕着 EXL2 格式设计的。而且 EXL2 可以在“bpw”bits per weight维度上灵活微调比如从 4.25 降到 3.75文件体积进一步缩小显存带宽压力变小速度自然就上来了这是我在 V100 上把速度推向 64 tok/s 的关键调整之一。还有个重要的原因ExLlamaV2 的显存缓存管理是静态预分配的加载时就能精确算出权重和缓存占多少显存很少出现 Transformers 那种运行到一半才临时申请显存导致 OOM 的情况。2.3 拿到量化模型的两种方式当天从零开始操作的话有两种拿模型的方式。第一种是直接下载社区量化好的 EXL2 格式。我这次用的模型是 Qwen2.5-27B-Instruct 的社区 EXL2 量化版网上能搜到 4.25bpw 和 3.75bpw 的版本。搜索关键词就是“Qwen2.5 27B EXL2”之类一般能在 HuggingFace 上找到。下载完一个目录就是完整的模型文件直接给推理引擎喂路径即可。第二种是自己量化。如果找不到信得过的版本可以用 ExLlamaV2 项目里的 convert 脚本把原始 FP16 模型转成 EXL2。大致流程是git clone https://github.com/turboderp/exllamav2 cd exllamav2 pip install -e . # 用校准数据集做量化--bpw 指定目标平均位宽 python convert.py -i ./Qwen2.5-27B-Instruct \ -o ./qwen27b-exl2-4.0bpw \ -cf qwen27b-exl2-4.0bpw \ --bpw 4.0自己量化的时候注意校准数据量不要太少我建议至少准备几百条多样化的中英文混合文本覆盖对话、代码、技术文档等场景。校准集如果太单一量化后的模型会在某些题材上出现明显智商下降。2.4 易踩坑的量化参数group size 与 desc_act选量化模型时有两个参数特别容易踩坑一个是 group size一个是 desc_act。group size 表示多少个权重共享同一个缩放因子。group size 越小量化粒度越细精度越高但计算开销也越大。常见的 128 是均衡点。我在 V100 上实测过group_size32 的版本精度略好但速度会掉 10% 左右group_size128 的速度和精度都很平衡。在 16GB 显存容量这么紧张的前提下我最终选择 group_size128。desc_act 全称是“按激活值重排通道”GPTQ 里常见它的本意是让量化误差更均匀但对推理 kernel 极不友好很多框架对 desc_actTrue 的模型无法使用融合反量化 kernel速度会骤降。当时我下过一个 GPTQ 版本标注了 desc_actTrue在 vLLM 和 ExLlamaV2 里都跑不顺换成 desc_actFalse 的版本立刻流畅了。后来我干脆只用 EXL2彻底躲开这个坑。注意如果看到描述里写着 “desc_act”, “act-order” 或 “ActOrder”先想清楚你的推理框架是否支持不支持就直接换版本别浪费时间在 kernel 兼容性上。3. 推理引擎切换带动速度起飞的核心加速3.1 引擎比量化更关键很多人会默认“换量化格式 提速”但这次复盘我最大的感受是量化只能帮你把模型塞进显存真正把速度打上去的是推理引擎。同一个 EXL2 4.25bpw 模型在 Transformers 里可能还是 5-10 tok/s在 ExLlamaV2 里轻轻松松到 25 tok/s。原因在于 ExLlamaV2 做了几件很关键的事。第一它的解码循环是静态的算子全部预编译不用像 PyTorch 动态图那样每次生成都重新调度第二它把所有反量化、去量化、矩阵乘法算子融合成了专用 CUDA kernel权重保存在显存里的布局直接针对连续读取优化第三它默认开启了 CUDA Graph 之类的中间表示优化把多步映射固化成一次启动。这些优化叠加起来等于把 V100 的显存带宽和 Tensor Core 都往死里压榨。换一个更贴近生活的类比Transformers 像是在每条街都停车再起步的货运司机ExLlamaV2 则是上高速之前把全程路线一次性规划好、油门踩到底的货车司机。同样的车同样的货百公里油耗不变但单位时间送的货量完全不一样。3.2 ExLlamaV2 部署实录环境上我用的是一台 Ubuntu 服务器显卡驱动版本 535CUDA 12.1PyTorch 2.1ExLlamaV2 运行需要 PyTorch但实际计算大多走自己的 kernel。安装流程很简单conda create -n exl2 python3.10 conda activate exl2 pip install torch --index-url https://download.pytorch.org/whl/cu121 git clone https://github.com/turboderp/exllamav2 cd exllamav2 pip install -e .然后写一个最小推理脚本做验证核心逻辑是这样的import torch from exllamav2 import (ExLlamaV2, ExLlamaV2Config, ExLlamaV2Cache, ExLlamaV2Tokenizer, ExLlamaV2StreamingContext) config ExLlamaV2Config(./qwen27b-exl2-4.25bpw) model ExLlamaV2(config) model.load() cache ExLlamaV2Cache(model, max_seq_len8192, lazyTrue) model.forward(torch.empty((1, 0), dtypetorch.long), cachecache) tokenizer ExLlamaV2Tokenizer(./qwen27b-exl2-4.25bpw) streaming ExLlamaV2StreamingContext(model, tokenizer, cache, position_offsets[0]) input_ids tokenizer.encode(介绍一下大模型部署的步骤, add_bosTrue) streaming.begin_stream(input_ids, gen_settings{temperature: 0.7}) for _ in range(128): chunk, eos streaming.stream_forward() if eos: break print(tokenizer.decode(chunk), end, flushTrue)这里有个细节容易忽略lazyTrue是延迟分配 KV Cache如果显存紧张它会先试算不够再报错。第一次加载模型时model.load()会把所有权重搬进显存加载时间和模型体积正相关4bit 的 14GB 模型大约 30-60 秒正常现象。如果你懒得写脚本也可以直接用项目里自带的 server 模式python exllamav2/server.py -m ./qwen27b-exl2-4.25bpw \ --max_seq_len 8192 --cache_mode Q8 --host 0.0.0.0 --port 8080它会起一个兼容 OpenAI 格式的 HTTP 接口主要拿来接客户端很方便。3.3 三条关键启动参数cache_mode、gpu_split、max_seq_len跑通只是第一步真正把速度从 25 推到 40 以上靠的是这三个参数的精细调节。第一个是cache_mode也就是 KV Cache 的量化模式。它能选 FP16、Q8、Q6、Q4 等。V100 显存带宽本来就紧张KV Cache 虽然不算最大头但每次生成也都要读写量化之后能省带宽也能省显存。我在短上下文2K 以内场景下试过FP16 和 Q8 的速度差别不大但一旦上下文超过 4KQ8 的优势就非常明显。最终为了稳我 fix 到 Q8。第二个是gpu_split单卡场景其实是“把哪些显存预算分给权重哪些分给缓存”。默认的 auto 模式在 16GB 卡上表现还行但我手动指定--gpu_split 16反而更稳相当于把 16GB 全部分给 GPU 推理不留一点给 CPU 卸载。如果分错了比如留了 2GB 给 CPU那么超出部分会跑到系统内存速度直接断崖式下跌。第三个是max_seq_len这是最容易掉坑的参数。V100 只有 16GB27B 模型权重已经吃掉 14GB能分给 KV Cache 的空间大概只有 1-2GB。按 Q8 缓存算4K 上下文可能就要 500MB 以上。如果你把 max_seq_len 设成 32768光 KV Cache 头几个 GB 就把显存塞爆系统要么 OOM要么偷偷卸载权重到 CPU速度打回原形。提示我在 V100 上最终把 max_seq_len 控制在 8192再加 Q8 缓存刚好能稳定跑完整上下文。如果你的业务需要更长上下文建议直接换更大的显存卡或者换 14B 模型别硬扛。3.4 从 4 到 64 的性能里程碑复盘把整体调优路径拉出来看会发现提速不是一次完成的是分阶段的阶段配置速度核心变化初始Transformers bitsandbytes 4bit4 tok/s基线动态图调度效率极低阶段一ExLlamaV2 EXL2 4.25bpw25 tok/s换引擎kernel 融合与静态图生效阶段二增加 KV Cache Q8、调低 max_seq_len40 tok/s显存不再交换全部推理留在 GPU阶段三换 EXL2 3.75bpw、微调缓存预算64 tok/s权重体积缩小带宽压力进一步下降阶段一到二的核心不是“优化了 kernel”而是“消除了显存瓶颈”阶段二到三才是真正通过减小每 token 的权重读取量来逼近带宽极限。后面我详细算给你看。4. 深入榨干带宽64 tok/s 背后的物理极限4.1 解码阶段为什么是“带宽游戏”要理解 64 tok/s 是怎么来的得先搞清楚大模型生成一个 token 时发生了什么。自回归生成是逐 token 进行的生成第 N 个 token 时需要把模型所有层、所有权重都参与一次前向计算。虽然计算量大但更关键的是每一层都要读取该层的权重矩阵。在 4bit 量化下的 27B 模型每生成一个 tokenGPU 要从显存读取约 13-14GB 的权重数据。哪怕这些读取结果能部分复用KV Cache 中的历史计算结果已经存好不需要重复算 attention 的历史部分但权重数据的读取是不可避免的。所以单流生成速度的上限约等于“显存带宽 ÷ 每 token 需要读取的权重字节数”。这是一个非常硬的物理限制跟你用多么高级的推理框架、做了多少 kernel 优化都无关。4.2 64 tok/s 已经是 V100 的极限区间我们来算一下账。V100 的 HBM2 显存带宽是 900GB/s 左右如果模型文件是 EXL2 4.25bpw权重约 27B × 0.53125 字节 ≈ 14.3GB理论最大速度 900 ÷ 14.3 ≈ 62.9 tok/s。如果模型文件是 EXL2 3.75bpw权重约 27B × 0.46875 字节 ≈ 12.7GB理论最大速度 900 ÷ 12.7 ≈ 70.9 tok/s。如果模型是 FP16权重 54GB理论最大速度 900 ÷ 54 ≈ 16.7 tok/s。这就能解释为什么我最后换到 3.75bpw 时能跑到 64 tok/s——它已经非常接近 70.9 tok/s 这个理论上限了。实际上还要算上 KV Cache 读取、激活值计算、内核启动等额外开销所以 64 基本可以理解为“V100 上的水位线”。当时我跑出一个很典型的 benchmark 输出Average tokens/sec: 64.05 Average throughput: 850.23 MB/s850MB/s 对应的正好接近“读取约 13GB 权重 少量 KV Cache”的带宽占用率。看到这个数据我就明白了不是模型还能更快而是 V100 的带宽就这么多再往上的空间已经很小。这也是我前面一直强调“V100 能跑 27B 的关键是显存带宽”的原因。你可能觉得 V100 算力 112 TFLOPS 很强但在 4bit 量化的自回归解码场景算力根本不是瓶颈带宽才是。一张算力低但带宽高的卡比如某些专为推理设计的卡在单流解码上的表现反而可能更好。4.3 还想更快方向是降低权重位宽或并行既然单流已经顶到带宽极限还想往 70 走只有两个大方向。第一个方向是继续降低权重位宽。EXL2 可以做到 3.0bpw、2.5bpw文件体积更小理论上限更高。但位宽过低带来的问题是精度明显下降模型的对话能力、数学推理能力都会打折扣需要在实际业务上做效果评估不是越低越好。我在试过 3.5bpw 之后还是保留了 3.75bpw算是速度和质量的平衡点。第二个方向是提升吞吐而不是单流速度。如果你要服务多个用户别死磕单流 tok/s而是用连续批处理continuous batching把多个请求拼成一个 batch 同时推理。ExLlamaV2 的 server 模式、或者 vLLM 的调度器都是干这个的。单流 64 tok/s 不变但 4 个并发流的总吞吐可能跑到 150-200 tok/s对 API 服务来说这个数字更有意义。注意投机解码speculative decoding也是理论上能突破单流速度的方案用一个小的 draft 模型预测多个 token再用大模型批量验证能把有效生成速度提高 1.5-2 倍。但 V100 上要额外跑一个小模型显存预算更紧张我这次没有实际部署。如果你显存有富余可以值得一试。5. V100 部署 27B 的常见坑位与排查清单5.1 显存溢出先看这三项整个过程里我遇到最多的报错就是 OOM 和“CUDA out of memory”。排查顺序基本固定第一步确认 max_seq_len。KV Cache 占多少直接跟序列长度挂钩。如果你的业务实际只有 2K 上下文就别把 max_seq_len 设成 8192。调低这一项通常能瞬间腾出 1GB 以上显存。第二步KV Cache 量化。ExLlamaV2 里的 cache_mode 从 FP16 切到 Q8 或 Q4能省一半以上缓存显存。代价是极微小的精度损失在对话场景几乎体感不到。第三步确认没有发生“隐式卸载”。有的框架在显存不足时会把部分层转移到 CPU 内存表面上程序还能跑速度掉到个位数。排查方法很简单监控显存占用是否稳定在 15GB 以上同时看 CPU 内存占用是否突然暴涨。如果是就把显存预算重新分配一下别让任何层落到 CPU。5.2 速度上不去还有这些隐藏瓶颈如果你已经换了 ExLlamaV2配置也对但速度还是上不去我建议按照下面这张表逐项排查现象可能原因处理方式速度只有个位数max_seq_len 过大导致缓存不完整发生权重重加载调低 max_seq_len量化 KV Cache速度 20 左右上不去模型格式不是 EXL2或量化版本未针对 kernel 优化检查模型目录确认用 EXL2 格式首 token 慢后续稳定模型加载预热时间CUDA kernel 编译多测几次忽略首轮延迟速度波动大系统内存交换、温度降频、其他进程抢显存关掉其他进程用 nvidia-smi 监控温度CPU 占用很高数据预处理、tokenizer 成为瓶颈用静态 batch 或预分词减少 Python 侧循环另外有个很容易被忽略的点显存温度。V100 长时间满载跑推理温度到 85°C 以上之后会自动降频频率一降显存带宽和算力都会缩水。我当时专门用nvidia-smi -pl限制功耗墙并给机箱加了一把风扇温度稳定下来后速度也更稳定。5.3 V100 专属坑位清单给同样用 V100 的朋友整理几个我踩过的专属坑第一V100 的 sm_70 计算能力让很多新库默认不支持。ExLlamaV2 的兼容性还行但某些更底层的 CUDA kernel 库可能要求 sm_80。遇到不支持的报错不要急着换库先查计算能力是否匹配。第二FlashAttention 在 V100 上需要特定版本。新版 flash-attn 有些只支持 sm_80如果装不上可以退回 xformers 或者 ExLlamaV2 自带的注意力 kernel。ExLlamaV2 自带了一套“半精度注意力”实现不需要额外装 FlashAttention 也能跑。第三驱动和 CUDA 版本必须配好。V100 老卡用太老的驱动可能没法跑新 PyTorch用太新的 CUDA 又可能有兼容问题。我最终稳定在 CUDA 12.1 PyTorch 2.1一切正常。5.4 一些实战中的小技巧最后分享几个调优现场学到的细节技巧虽然不是决定性的但很实用。一是用torch.cuda.set_per_process_memory_fraction给 PyTorch 设置显存使用上限可以防止一上来就把显存占满导致内核启动失败。在 ExLlamaV2 里也可以直接用环境变量限制可用显存预留一点点空间给 CUDA context。二是 benchmark 脚本要走“预热 多次取平均”的流程。第一次调用会触发 kernel 编译和缓存预热数值虚低。我当时用 128 token 的固定 prompt连续生成 3 次取后两次平均数据才稳定可信。三是模型路径里的空白字符会导致配置解析出错。当时我把模型放在/data/tmp/qwen27b exl2因为中间有个空格ExLlamaV2 直接报错折腾了半小时才找到原因。换成没有空格的路径就没事。这个真的有点蠢但确实隐藏得很深。四是可以写一个小脚本每次启动前自动打印显存剩余量、模型显存占用和 KV Cache 预估占用。这样一旦 OOM能立刻看出来是哪个环节爆的。我自己写的是一个 20 行 Python 脚本用pynvml读显存用 ExLlamaV2 的配置对象里的属性做估算配合输出一目了然。在整个调优过程中我最深的体会是V100 虽然老但它显存带宽 900GB/s 这个底子还在4bit 量化下的 27B 模型完全有得跑。真正的瓶颈从来不是显存不够大而是你选的推理链路有没有把每次生成都控制在显存带宽的上限附近。4 到 64 的跨越本质上不是某个单点优化拉动的而是量化选型、引擎切换、显存预算管理、权重位宽取舍这几个环节层层叠加的结果。如果你手头也有一块 V100或者别的 16GB 老卡我建议别急着换硬件先照着这条路径把量化格式换成 EXL2、推理引擎换成 ExLlamaV2、再把 KV Cache 和上下文长度规划好大概率也能把 27B 级别的模型压榨到接近 60 tok/s 的水平。跑通之后你会发现自己对显存、带宽、量化、推理链路这套机制的理解比用 A100 跑通一个大模型要深得多。
返回列表