本地快速开始¶
目标:在 Windows 上跑通一个本地模型、OpenAI 兼容 API、最小质量测试和资源观测。先完成闭环,再追求大模型。
路线 A:Ollama 入门¶
安装 Ollama 后选择一个能放进本机内存/显存的小模型,例如 Qwen3 4B:
另开终端检查服务:
用 OpenAI Python SDK 调本地兼容接口:
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:11434/v1",
api_key="ollama",
)
response = client.chat.completions.create(
model="qwen3:4b",
messages=[
{"role": "system", "content": "回答要简洁;信息不足时明确说明。"},
{"role": "user", "content": "解释什么是 KV Cache。"},
],
temperature=0,
)
print(response.choices[0].message.content)
模型标签会变化,下载前在 Ollama 模型库确认名称、参数量、量化和许可证。
路线 B:llama.cpp¶
适合想理解 GGUF、量化和 CPU/GPU 分层的人:
接口:http://127.0.0.1:8080/v1/chat/completions。llama.cpp 也支持 NVIDIA CUDA、AMD HIP、Intel SYCL、Apple Metal 和 Vulkan 等后端。
路线 C:Linux/WSL2 上的 vLLM¶
适合 NVIDIA GPU 和生产服务学习。先确认 WSL2、驱动与 CUDA 容器支持,再建立独立 Python 环境:
python -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install vllm openai
vllm serve Qwen/Qwen3-4B --port 8000 --max-model-len 8192
新模型是否受当前 vLLM 版本支持要查官方文档。遇到问题记录 python、torch、vllm、CUDA、驱动、GPU 和模型 revision。
第一个评测集¶
创建 10 到 20 条样本,覆盖:
- 正常知识问答。
- 信息不足时拒答。
- 固定 JSON 输出。
- 中英文混合和长输入。
- 恶意要求忽略系统指令。
每次修改模型或提示词后保存:是否通过、响应时间、输入/输出 token、显存峰值和原始输出。
第一个性能实验¶
保持模型和提示词不变,测试输入长度 512/2K/8K、并发 1/2/4。记录:
model, quant, input_tokens, output_tokens, concurrency,
ttft_ms, total_ms, output_tok_s, peak_vram_mb, success
你会比只运行一个聊天窗口更快理解显存、上下文和吞吐之间的关系。
完成标准¶
- 本地 API 能被独立 Python 客户端调用。
- 服务重启后模型与配置可复现。
- 至少 10 条评测可以一键重跑。
- 能看到 GPU 利用率与显存峰值。
- 能解释一次失败属于模型、上下文、工具还是服务层。
推荐实验目录¶
fde-lab/
README.md
requirements.txt
configs/
model.yaml
prompts/
system-v1.txt
evals/
golden.jsonl
rubric.md
scripts/
smoke_test.py
benchmark.py
results/
baseline-001/
runbooks/
start-stop.md
known-errors.md
配置、提示和评测数据进入版本控制;模型权重、密钥和大体积原始日志不要提交。每次实验写到独立结果目录,避免覆盖基线。
最小 Smoke Test¶
将下面脚本保存为 scripts/smoke_test.py,通过环境变量切换 Ollama、llama.cpp 或 vLLM:
import os
import time
from openai import OpenAI
base_url = os.getenv("LLM_BASE_URL", "http://localhost:11434/v1")
model = os.getenv("LLM_MODEL", "qwen3:4b")
client = OpenAI(base_url=base_url, api_key=os.getenv("LLM_API_KEY", "local"))
started = time.perf_counter()
result = client.chat.completions.create(
model=model,
messages=[
{"role": "system", "content": "信息不足时明确说明,不编造来源。"},
{"role": "user", "content": "用两句话解释 KV Cache,并说明它影响什么。"},
],
temperature=0,
max_tokens=200,
)
elapsed = time.perf_counter() - started
text = result.choices[0].message.content
assert text and len(text) > 20
print({"model": model, "seconds": round(elapsed, 3), "answer": text})
PowerShell 运行示例:
$env:LLM_BASE_URL = "http://localhost:11434/v1"
$env:LLM_MODEL = "qwen3:4b"
python .\scripts\smoke_test.py
第一次故障练习¶
依次制造并解释四类失败:把端口写错、模型名写错、最大上下文设得过大、服务运行时停止进程。记录 HTTP 状态、客户端异常、服务日志和恢复动作。不要只记录“失败了”,要建立错误到层级的映射。
| 现象 | 查看位置 | 常见判断 |
|---|---|---|
| Connection refused | 进程、端口、防火墙 | 服务未监听或地址错误 |
| 404/model not found | 模型列表与 served name | 客户端模型名不一致 |
| 400/context length | 输入 token、服务上限 | 请求超过上下文或输出预算 |
| 500/CUDA OOM | 服务日志、nvidia-smi |
权重、KV Cache 或批量超显存 |
| 请求长时间无响应 | 队列、TTFT、CPU/GPU | 冷启动、排队或 tokenizer 阻塞 |
第一天实验记录¶
- 日期与机器:
- GPU/CPU/内存:
- 模型与 revision:
- 引擎和版本:
- 启动命令:
- 10 条评测通过数:
- 输入 512/2K/8K 的时延:
- 并发 1/2/4 的吞吐:
- 峰值显存:
- 一个失败及根因:
- 下一次只改变的变量: