跳转到内容

CTranslate2 — Transformer 模型推理的 C++ 加速引擎

是什么

CTranslate2(CT2)是 OpenNMT 团队写的一个 C++/Python 库,专门让 Transformer 模型推理时跑得更快、更省内存

日常类比:原版 PyTorch 模型像一辆装了全套训练设备的卡车——能跑、能改、能学,但很重。CT2 把这辆车开进改装车间,拆掉训练相关的零件,换上轻量化车壳和经过特调的发动机,只保留”开起来”这一件事。结果是同一段路,新车快 2-4 倍,油耗降一半。

技术上 CT2 做了两件事:

  1. converter:读 PyTorch / TensorFlow / HuggingFace 模型权重,转换成自家定义的中间表示(IR)格式,存进磁盘。
  2. runtime:用 C++ 写的推理内核读这个 IR,绕开 Python,配合 INT8 / FP16 量化执行。

为什么重要

不理解 CT2 解决的问题,下面这些事很难看明白:

  • 为什么 faster-whisper 比官方 openai/whisper 快 2-4 倍但模型权重相同
  • 为什么 NLLB-200 这种 5GB 的翻译模型能在 8GB 内存的 Mac 上流畅跑
  • 为什么 SYSTRAN(CT2 出品方)能把翻译 SaaS 做成毛利生意——核心就是这个引擎省下来的算力
  • 为什么”模型部署”是一门和”模型训练”完全不同的工程学科

通用结论:训练用 PyTorch,部署换专用 runtime——CT2 是 Transformer 这一族里最成熟的那个。

核心要点

CT2 的快可以拆成 三层

  1. IR + converter:先把 PyTorch 计算图固化成纯权重 + 算子描述,去掉 Python 的动态性。类比:把菜谱从”边做边想”变成”按编号执行的工序卡”。

  2. C++ 内核 + 自动调度:检测 CPU 是 x86-64 还是 ARM,是否有 AVX-512 / NEON,自动挑最快的代码路径。GPU 路径用 cuBLAS / cuDNN。

  3. 量化(quantization):把 FP32 权重压成 FP16 / INT8 / INT4。INT8 把 32 位浮点改成 8 位整数,模型体积砍到 1/4,速度上 2-3 倍,BLEU 掉 0.5 以内——绝大多数场景可接受。

三层组合起来,覆盖三类模型:

  • encoder-decoder:Transformer / NLLB / BART / T5 / Whisper(翻译、语音转文字)
  • decoder-only:GPT / Llama / Mistral / Gemma(聊天补全)
  • encoder-only:BERT / XLM-RoBERTa(分类、向量化)

实践案例

案例 1:把 Whisper 转成 CT2 + INT8 量化

Terminal window
pip install ctranslate2 transformers
ct2-transformers-converter \
--model openai/whisper-large-v2 \
--output_dir whisper-large-v2-ct2-int8 \
--quantization int8

转换完成后磁盘上是一个目录,里面有 model.bin(权重)+ config.json(结构描述)+ tokenizer 文件。和原版同名但体积砍到 1/4

案例 2:用 Python API 跑批量翻译

import ctranslate2
import sentencepiece as spm
translator = ctranslate2.Translator('nllb-200-3.3B-ct2-int8', device='cpu')
sp = spm.SentencePieceProcessor('flores200_sacrebleu_tokenizer_spm.model')
src = ['Hello, world.', 'How are you?']
tokens = [['__eng_Latn__'] + sp.encode(s, out_type=str) + ['</s>'] for s in src]
results = translator.translate_batch(tokens, target_prefix=[['__zho_Hans__']] * 2)
for r in results:
print(sp.decode(r.hypotheses[0][1:]))

关键点translate_batch 自带异步 + 动态批处理,不用手写线程池。

案例 3:faster-whisper 是怎么快的

from faster_whisper import WhisperModel
model = WhisperModel('large-v2', device='cuda', compute_type='int8_float16')
segments, info = model.transcribe('audio.mp3', beam_size=5)

底层就是 CT2 + Whisper 权重转换。性能对比(large-v2,单卡 RTX 3090):

实现精度时长显存
openai/whisperFP162m23s4525MB
faster-whisperFP161m03s4525MB
faster-whisperINT80m59s2926MB
faster-whisperINT8 + batch=80m16s同上

同一份模型权重,runtime 换掉 → 2-4 倍加速 + 35% 显存下降。这就是 CT2 的杀伤力。

踩过的坑

  1. 必须先 convert,不能即转即用:CT2 不像 PyTorch 那样能直接 load HuggingFace。新模型架构出来要等 CT2 团队加适配(一般 1-2 周)。

  2. INT8 在低资源语言对会掉点:高资源语言(英中、英法)BLEU 掉 0.3 以内可忽略;但小语种或专业领域可能掉 1-2 BLEU——上线前必须用真实测试集校准。

  3. GPU 路径绑 cuDNN / cuBLAS 版本:CT2 编译时锁定 CUDA 版本,环境不对直接段错误。生产环境推荐用官方 docker。

  4. 动态 batch 不限大小会爆显存max_batch_size 必须显式设。CT2 的调度器倾向”塞满 batch 再发车”,不限就会把所有请求合一起。

  5. Whisper streaming 要自己拼 VAD:CT2 本身只做单段推理,实时转录得在前面接 VAD(语音活动检测)切片。WhisperLive 项目把这一段做完了,可参考。

适用 vs 不适用场景

适用

  • 翻译服务、语音转文字、文本分类——Transformer encoder-decoder / encoder-only 是 CT2 最强项
  • 需要在 CPU 上跑大模型(比如笔记本本地跑 Whisper)—— INT8 + AVX-512 是杀手锏
  • 翻译类 SaaS、本地化工作流、字幕生成——稳定、低延迟、可量化

不适用

  • 还在迭代结构的研究模型——converter 跟不上
  • 大型 LLM serving(Llama-70B 多卡)——选 vLLM,PagedAttention 更适合长上下文
  • 训练或微调——CT2 只做推理,训练用回 PyTorch
  • 用了奇怪自定义算子的模型——CT2 算子库有限

历史小故事(可跳过)

  • 2019 年:OpenNMT(Harvard NLP + SYSTRAN 合作的开源翻译框架)发布 CTranslate v1,那时只是 OpenNMT-py 的推理后端。
  • 2021 年:v2 重写,改名 CTranslate2,定位从”OpenNMT 配件”变成”通用 Transformer 推理引擎”,开始支持 HuggingFace 模型。
  • 2022-2023 年faster-whisper 项目把 CT2 推到主流视野——一夜之间所有”想跑 Whisper 但 GPU 不够”的开发者都在用。
  • 2024 年至今:加入 AWQ / INT4 / Llama / Gemma 支持,逐步覆盖 LLM 场景,但和 vLLM 的定位错开(CT2 偏 encoder-decoder + 量化,vLLM 偏 decoder-only + 高吞吐 serving)。

学到什么

  1. 训练框架和推理引擎应该分家:PyTorch 灵活但慢,专用 runtime 快但僵——上线时换引擎是工程常识,不是过早优化。
  2. IR 是性能优化的支点:把动态计算图固化成静态 IR,才能做算子融合、量化、调度。LLVM、ONNX、CT2 的内部 IR 思路一脉相承。
  3. 量化不是免费午餐但接近免费:INT8 让模型体积 -75%、速度 +200%、精度 -1%——大多数业务可接受这个 tradeoff。
  4. 垂直场景的专用工具能赢通用框架:CT2 不追求覆盖所有模型,只把 Transformer 推理这一件事做到极致——这是开源项目活下来的常见姿态。

延伸阅读

关联

  • whisper —— OpenAI 语音识别模型,CT2 让它能在普通笔记本跑
  • transformer —— CT2 的服务对象就是这个架构家族
  • quantization —— INT8 / INT4 量化的理论基础
  • onnx —— 另一种”模型 IR”思路,覆盖更广但 Transformer 优化更浅
  • vllm —— LLM serving 的另一选择,定位互补不冲突