适用场景
Kolibri 是德语区发布的一类开放权重语言模型,主打"主权 AI"路线:权重可下载、可在自有硬件上运行、数据不出内网。这套方案适合三类人:一是需要处理德语合同、邮件、客服工单,但数据不能出境的团队;二是想给内部知识库接一个可控推理后端的运维同学;三是做多语能力对比、需要固定版本做回归评测的算法工程师。整套流程的目标是:把权重拉下来,在私有环境跑通一次对话,再用一套可复现的小评测确认德语质量和多语表现。
环境与前置条件
- 操作系统:Ubuntu 22.04 / Debian 12 等主流 Linux 发行版。macOS 用 Apple Silicon 也可以跑量化版,但本文命令以 Linux 为准。
- Python:3.10 及以上,具体下限以模型卡和推理框架的官方文档为准。建议用 venv 或 conda 隔离环境。
- 显存(量级参考,实际以模型参数量为准):7B 级别权重以 bf16 加载约占 14–15 GB,加上 AI 词典:KV Cache">KV Cache 建议准备 24 GB 显存;用 4bit 量化(GPTQ/AWQ/GGUF Q4 级别)大约 5–8 GB 显存即可;纯 CPU 推理也能跑,但内存建议 16 GB 以上,速度会明显慢。
- 磁盘:权重本体通常在十几到几十 GB,量化副本、缓存、日志再留一倍,建议预留 100 GB。
- 网络:能访问 Hugging Face 或组织内部的模型仓库镜像。内网离线环境需要提前把权重目录打包拷入。
- 基础工具:
git、git-lfs、curl,以及pip。
一句话原则:模型名、参数量、上下文长度、许可条款,全部以官方发布页和模型卡上的当前版本为准,不要照抄任何博客里的版本号。
分步骤部署
第 1 步:确认模型来源与许可
先到官方发布页找到模型卡,确认三件事:权重仓库的准确名称(<组织名>/<模型名>)、权重格式(safetensors 还是 GGUF)、许可是否允许你的使用场景(商用、二次分发、蒸馏等)。
把仓库名和权重文件的 commit 版本记下来,后面做版本锁定时要用。这一步不产生任何命令输出,但决定了后面所有步骤能不能跑通。
第 2 步:创建隔离的 Python 环境
```bash
python3 -m venv ~/venvs/kolibri
source ~/venvs/kolibri/bin/activate
python -m pip install -U pip wheel
```
成功标志:命令行提示符前出现 (kolibri),python -V 输出预期版本。
接着安装下载与推理依赖:
```bash
pip install -U "huggingface_hub[cli]" hf_transfer
pip install -U torch transformers accelerate
```
hf_transfer 是可选的加速下载组件,内网带宽紧张时可以跳过。
第 3 步:下载权重到本地目录
```bash
export HF_HOME=/data/hf_home # 缓存目录,放在大盘上
export HF_HUB_ENABLE_HF_TRANSFER=1 # 用 hf_transfer 加速
mkdir -p /data/models
hf download <组织名>/<模型名> --local-dir /data/models/kolibri
```
说明:新版命令行工具是 hf download,旧版是 huggingface-cli download,两者等价,按你安装的版本选择。如果所在网络无法直连公共仓库,可设置 HF_ENDPOINT 指向组织内部或可信的镜像服务,具体地址以镜像提供方的文档为准。
成功标志:/data/models/kolibri 下出现 config.json、tokenizer.json、若干 .safetensors 分片等文件。用 du -sh /data/models/kolibri 看一下体积,和模型卡上的参数量对得上就正常。
第 4 步:用 transformers 跑一次最小推理
先写一个最小脚本 minimal_infer.py:
```python
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch
MODEL_DIR = "/data/models/kolibri"
tok = AutoTokenizer.from_pretrained(MODEL_DIR, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
MODEL_DIR,
torch_dtype=torch.bfloat16,
device_map="auto",
trust_remote_code=True,
)
messages = [{"role": "user",
"content": "Erkläre in drei Sätzen, was ein Vektor in der linearen Algebra ist."}]
prompt = tok.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
inputs = tok(prompt, return_tensors="pt").to(model.device)
with torch.no_grad():
out = model.generate(**inputs, max_new_tokens=256, do_sample=False)
print(tok.decode(out[0][inputs["input_ids"].shape[-1]:], skip_special_tokens=True))
```
```bash
python minimal_infer.py
```
这一步在做什么:验证权重能被正确加载、chat template 能被正确套用。如果模型卡上没有 chat template,就要手动按官方文档拼 prompt。
成功标志:终端打印出一段通顺的德语回答。同时开另一个窗口执行 nvidia-smi,能看到显存被占用、GPU 利用率有波动。
第 5 步:用 vLLM 起 OpenAI 兼容服务
单机脚本适合调试,对外提供服务建议用推理服务框架。
```bash
pip install -U vllm
python -m vllm.entrypoints.openai.api_server \
--model /data/models/kolibri \
--served-model-name kolibri \
--dtype bfloat16 \
--max-model-len 8192 \
--gpu-memory-utilization 0.90 \
--host 0.0.0.0 --port 8000
```
参数说明:--max-model-len 别一上来就顶到模型上限,先设小一点跑通再往上加;--gpu-memory-utilization 控制 KV Cache 的显存预留比例。如果显存紧张,可以换用量化权重,或改用 llama.cpp 的 GGUF 路线。
成功标志:日志里出现模型加载完成、监听 8000 端口的信息,进程不退出。
低显存或纯 CPU 的替代方案:用 llama.cpp。大致流程是先用仓库里的 convert_hf_to_gguf.py 把 safetensors 转成 GGUF,再用 llama-quantize 生成 Q4_K_M 级别的量化文件,最后用 llama-server 或 llama-cli 加载。脚本名称与参数以 llama.cpp 官方文档当前版本为准。
第 6 步:准备评测集并跑分
评测分两层:一层是公开基准(可选),一层是自建小集(必做,因为业务场景只有自己最清楚)。
公开基准可以用 lm-evaluation-harness:
```bash
pip install -U lm-eval
lm_eval --tasks list | grep -i german # 看当前版本内置了哪些德语任务
lm_eval --model local-completions \
--model_args base_url=http://127.0.0.1:8000/v1/completions,model=kolibri,tokenizer_backend=None \
--tasks <德语任务名> \
--num_fewshot 3 \
--output_path ./eval_out
```
任务名以 --tasks list 的实际输出和官方文档为准,任务清单会随版本变化。
自建评测更实用。写一个 eval_kolibri.py:
```python
import csv, time
from openai import OpenAI
client = OpenAI(base_url="http://127.0.0.1:8000/v1", api_key="EMPTY")
CASES = [
{"id": "de-01", "lang": "de",
"prompt": "Antworte auf Deutsch: Was ist der Unterschied zwischen Ist- und Soll-Zustand?",
"must_contain": ["Ist", "Soll"]},
{"id": "de-02", "lang": "de",
"prompt": "Schreibe eine kurze, formelle Absage für einen Termin am Freitag.",
"must_contain": None},
{"id": "de-03", "lang": "de",
"prompt": "Bilde den Konjunktiv II: Wenn ich mehr Zeit hätte, ...",
"must_contain": None},
{"id": "en-01", "lang": "en",
"prompt": "Summarize in one sentence why local inference matters for regulated industries.",
"must_contain": None},
{"id": "zh-01", "lang": "zh",
"prompt": "用中文解释什么是向量数据库,三句话以内。",
"must_contain": None},
]
rows = []
for c in CASES:
t0 = time.time()
r = client.chat.completions.create(
model="kolibri",
messages=[{"role": "user", "content": c["prompt"]}],
temperature=0,
max_tokens=256,
)
dt = time.time() - t0
text = r.choices[0].message.content
auto = ""
if c["must_contain"]:
auto = all(k.lower() in text.lower() for k in c["must_contain"])
rows.append({"id": c["id"], "lang": c["lang"],
"latency_s": round(dt, 2), "out_chars": len(text),
"auto_check": auto, "answer": text})
with open("eval_result.csv", "w", newline="", encoding="utf-8") as f:
w = csv.DictWriter(f, fieldnames=list(rows[0].keys()))
w.writeheader()
w.writerows(rows)
print("done -> eval_result.csv")
```
```bash
pip install -U openai
python eval_kolibri.py
```
德语评测建议覆盖这几个维度,每个维度准备 10–20 条:
1. 语法正确性:变格(Dativ/Akkusativ)、动词位置、Konjunktiv II。
2. 复合词处理:德语长复合词能否拆解正确,例如把复合名词拆成核心词加修饰语。
3. 语体匹配:正式信函要用 Sie 形式,不能混入 du。
4. 语言跟随:用德语提问必须用德语回答,不能漂移成英语。
5. 事实一致性:同一问题换三种问法,答案不应该互相矛盾。
多语评测的做法是"同义多问":把同一个业务问题分别用德、英、中、法四种语言提问,比较四份答案的结论是否一致、格式是否稳定。重点看两件事——小语种(德语)的表现是否明显弱于英语,以及跨语言是否会出现术语翻译不一致。
验证部署是否成功
按顺序执行以下检查:
```bash
1. 服务是否活着
curl -s http://127.0.0.1:8000/v1/models
```
预期:返回 JSON,data 里包含 "id": "kolibri"。
```bash
2. 一次真实对话
curl -s http://127.0.0.1:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "kolibri",
"messages": [{"role": "user",
"content": "Fasse in einem Satz zusammen, was ein Vektorraum ist."}],
"temperature": 0,
"max_tokens": 128
}'
```
预期:choices[0].message.content 是一段德语,句子完整、没有乱码、没有重复循环。
```bash
3. 显存与进程状态
nvidia-smi
```
预期:能看到 Python 进程占住显存,利用率在收到请求时上升、空闲时回落。
```bash
4. 评测脚本能跑完
python eval_kolibri.py && column -s, -t eval_result.csv | head -20
```
预期:生成 eval_result.csv,latency_s 和 out_chars 都有数值,auto_check 列出现 True。
四项都过了,说明从权重下载到本地推理再到评测的链路已经跑通。
常见报错与解决
1. OSError: We couldn't connect to 'https://huggingface.co'
→ 原因:网络无法直连模型仓库,或代理未生效。
→ 解决:配置组织内镜像地址或代理后再下载。
```bash
export HF_ENDPOINT=<组织内部镜像地址> # 以镜像提供方文档为准
或
export HTTPS_PROXY=http://<代理地址>:<端口>
hf download <组织名>/<模型名> --local-dir /data/models/kolibri
```
2. torch.cuda.OutOfMemoryError: CUDA out of memory
→ 原因:权重加 KV Cache 超过显存,通常出现在 max-model-len 设得过大或并发请求过多时。
→ 解决:先降上下文长度和显存占用比例,再考虑量化。
```bash
python -m vllm.entrypoints.openai.api_server \
--model /data/models/kolibri --served-model-name kolibri \
--max-model-len 4096 --gpu-memory-utilization 0.80 --max-num-seqs 4 \
--host 0.0.0.0 --port 8000
```
显存仍然不够,就改用量化权重或 llama.cpp 的 GGUF 路线。
3. ValueError: Tokenizer class ... does not exist 或 trust_remote_code 相关报错
→ 原因:模型使用了自定义建模代码,默认不允许远程执行。
→ 解决:确认代码来源可信后显式开启。
```python
AutoTokenizer.from_pretrained(MODEL_DIR, trust_remote_code=True)
AutoModelForCausalLM.from_pretrained(MODEL_DIR, trust_remote_code=True)
```
4. 401 Client Error: Unauthorized 或 403 Forbidden
→ 原因:仓库需要登录并接受许可协议。
→ 解决:先登录,再确认已在模型页接受条款。
```bash
hf auth login # 旧版为 huggingface-cli login
hf download <组织名>/<模型名> --local-dir /data/models/kolibri
```
5. The model's max seq len is larger than the maximum number of tokens
→ 原因:--max-model-len 超过了模型位置编码支持的长度,或 KV Cache 装不下。
→ 解决:把该参数降到模型卡声明上限以内。
```bash
python -m vllm.entrypoints.openai.api_server \
--model /data/models/kolibri --served-model-name kolibri \
--max-model-len 4096 --host 0.0.0.0 --port 8000
```
6. 输出重复、答非所问、用德语问却回英语
→ 原因:chat template 没套用,或采样参数不合适。
→ 解决:确认推理时走了 apply_chat_template,评测时把 temperature 设为 0;如果模板缺失,按模型卡的手册手动拼接 <|user|> 一类的角色标记。
后续维护
备份:权重目录做一次冷备,记录下载时的 commit 版本号(hf download 日志里会打印)。环境也要备份——pip freeze > requirements.lock,连同模型版本一起归档。这样半年后要复现某个评测结果时不会抓瞎。
升级:模型仓库和推理框架都会迭代。原则是先在小机器或单卡上跑通新版本,跑一遍第 6 步的评测集,确认德语任务没有回退,再滚动切换生产服务。旧版本权重不要删,保留至少一个可回滚的版本,切换时改软链接或配置项即可。
日志:vLLM 的访问日志里关注三件事——请求量、延迟分位数、报错堆栈。把日志按天轮转,避免把模型盘写满。
监控:至少盯住 GPU 利用率、显存占用、请求队列长度和 P95 延迟。显存缓慢上涨而请求量没变,通常意味着有长上下文请求把 KV Cache 顶满了,需要调 max-model-len 或加限流。
评测回归:把 eval_kolibri.py 和那份德语样本集放进版本库,每次换模型、换框架版本、改推理参数都跑一遍,把 eval_result.csv 存成带日期的文件。长期积累下来,你会得到一条属于自己业务场景的质量曲线,比任何公开榜单都更有参考价值。
最后提醒一句:主权模型的价值在于可控,而可控的前提是可复现。把权重来源、版本号、推理参数、评测脚本四样东西固定下来,这套部署才算真正落地。
