ARTICLE DETAIL

资讯详情

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

一文详解大模型推理:从基础知识到 vLLM 的配置与验证

一文详解大模型推理:从基础知识到 vLLM 的配置与验证 1. 大模型推理到底在做什么从预填充到解码的完整链路大模型推理LLM Inference是把训练好的权重加载进显存接收你的提示词然后一个 token 一个 token 地把回答“吐”出来的过程。它和训练最大的区别在于训练是并行处理整段文本、反复更新权重推理是自回归生成每生成一个新 token 都要依赖前面所有 token 的中间状态。理解这一点你才能明白为什么推理服务的瓶颈往往不在算力而在显存带宽和 KV Cache 的调度。推理过程分成两个阶段。预填充Prefill阶段模型一次性处理你输入的整段提示词因为所有 token 都是已知的可以并行计算同时把注意力机制里的 Key/Value 中间状态缓存下来这就是 KV Cache。解码Decode阶段模型基于提示词和已生成的 token一次只生成一个新 token无法并行所以这个阶段最耗时。你感受到的“打字机效果”本质就是解码阶段在逐个输出。对想跑通本地推理服务的开发者来说需要关注几个核心指标。TTFTTime to First Token是第一个 token 的时间决定用户点下发送后要等多久才看到回应TPOTTime Per Output Token是每个输出 token 的时间决定后续文字流出的速度吞吐量则是整个服务每秒能生成多少 token决定并发能力。vLLM 之所以流行就是因为它用 PagedAttention 管理 KV Cache、用连续批处理Continuous Batching提升吞吐让单卡也能扛住不错的并发。这一篇的目标很明确带你从零把 vLLM 推理服务跑起来给出可复制的启动命令、配置骨架和请求验证动作。如果你手头暂时没有本地 GPU或者想先快速验证模型行为再决定部署方案也可以先用 TaoToken 的模型对话能力做接口联调确认请求格式和返回结构再迁移到本地 vLLM。2. 前置准备环境、模型与 TaoToken 接入信息2.1 硬件与驱动检查vLLM 对显存有硬性要求。以 7B 模型为例bf16 精度下权重约占 14GB加上 KV Cache 和激活内存建议单卡 24GB 起步。先用一条命令确认 GPU 状态nvidia-smi --query-gpuname,memory.total,memory.used,driver_version --formatcsv输出里重点看memory.total和driver_version。驱动版本建议 535 以上CUDA 版本 12.1 以上。如果显存不够后面可以通过--gpu-memory-utilization和量化参数压缩占用。2.2 Python 环境与 vLLM 安装建议用独立虚拟环境避免和系统里的 torch 版本打架python3 -m venv vllm-env source vllm-env/bin/activate pip install --upgrade pip pip install vllm安装完成后验证版本python -c import vllm; print(vllm.__version__)如果这一步报 CUDA 相关错误多半是 torch 和驱动不匹配可以先用pip install torch --index-url https://download.pytorch.org/whl/cu121固定 torch 版本再装 vLLM。2.3 模型下载与 TaoToken 接入模型可以从 Hugging Face 拉取也可以用 ModelScope 加速。以 Qwen2.5-7B-Instruct 为例huggingface-cli download Qwen/Qwen2.5-7B-Instruct --local-dir ./models/qwen2.5-7b-instruct如果你在联调阶段想先用云端接口验证请求格式可以到 TaoToken 控制台创建一个 API Key接口地址是https://taotoken.net/api。它的请求结构和 OpenAI 兼容方便你把同一套客户端代码在云端和本地 vLLM 之间切换。创建 Key 的入口在控制台的 API Keys 页面模型对话入口可以用来快速测试提示词效果。注意本地 vLLM 和云端接口的 base_url 不同本地默认是http://localhost:8000/v1云端是https://taotoken.net/api/v1。切换时只改 base_url 和 api_key 即可请求体保持一致。3. 可复制的 vLLM 启动配置与 settings.json 骨架3.1 最小可用启动命令先把服务跑起来再逐步加参数。最简启动python -m vllm.entrypoints.openai.api_server \ --model ./models/qwen2.5-7b-instruct \ --served-model-name qwen2.5-7b \ --host 0.0.0.0 \ --port 8000 \ --dtype bfloat16 \ --gpu-memory-utilization 0.90 \ --max-model-len 8192逐项说明--served-model-name是客户端调用时用的模型名可以和路径不同--gpu-memory-utilization 0.90表示最多用 90% 显存留一点给系统--max-model-len控制最大上下文长度设太大 KV Cache 会吃满显存。启动成功后终端会打印Uvicorn running on http://0.0.0.0:8000。3.2 生产向参数调优并发上来后需要调这几个参数python -m vllm.entrypoints.openai.api_server \ --model ./models/qwen2.5-7b-instruct \ --served-model-name qwen2.5-7b \ --host 0.0.0.0 \ --port 8000 \ --dtype bfloat16 \ --gpu-memory-utilization 0.92 \ --max-model-len 16384 \ --max-num-seqs 64 \ --max-num-batched-tokens 8192 \ --enable-prefix-caching \ --swap-space 8--max-num-seqs控制同时处理的序列数越大吞吐越高但显存越紧张--enable-prefix-caching对多轮对话场景很关键相同前缀的请求可以复用 KV Cache--swap-space是 CPU 交换空间显存不足时把部分 KV 换出到内存。实测下来7B 模型在 24GB 卡上max-num-seqs设 32 到 64 比较稳。3.3 settings.json 与 config.toml 骨架如果你用客户端工具或自建网关管理多个后端可以准备一份配置文件。settings.json骨架{ default_model: qwen2.5-7b, providers: { local-vllm: { base_url: http://localhost:8000/v1, api_key: EMPTY, model: qwen2.5-7b, timeout: 120 }, taotoken: { base_url: https://taotoken.net/api/v1, api_key: 你的_API_KEY, model: qwen2.5-7b, timeout: 60 } }, generation: { temperature: 0.7, top_p: 0.9, max_tokens: 2048 } }对应的config.toml骨架[server] host 0.0.0.0 port 8000 [model] path ./models/qwen2.5-7b-instruct served_name qwen2.5-7b dtype bfloat16 max_model_len 16384 [memory] gpu_memory_utilization 0.92 swap_space 8 [batching] max_num_seqs 64 max_num_batched_tokens 8192 enable_prefix_caching true这两份配置的作用是把启动参数和客户端参数分离方便你在不同环境间切换。本地调试用local-vllm需要对比云端行为时切到taotoken。4. 请求验证从 curl 到 Python 客户端4.1 用 curl 做最小验证服务起来后先确认健康检查curl http://localhost:8000/health返回{status:ok}说明服务正常。然后发一个补全请求curl http://localhost:8000/v1/chat/completions \ -H Content-Type: application/json \ -d { model: qwen2.5-7b, messages: [ {role: user, content: 用一句话解释什么是KV Cache} ], temperature: 0.7, max_tokens: 128 }返回体里choices[0].message.content就是模型输出usage字段会给出 prompt_tokens 和 completion_tokens方便你算吞吐。4.2 Python 客户端验证用 OpenAI SDK 可以直接对接因为 vLLM 兼容 OpenAI 接口from openai import OpenAI import time client OpenAI( base_urlhttp://localhost:8000/v1, api_keyEMPTY ) start time.time() resp client.chat.completions.create( modelqwen2.5-7b, messages[{role: user, content: 写一个Python快速排序}], temperature0.7, max_tokens256 ) elapsed time.time() - start print(resp.choices[0].message.content) print(f耗时: {elapsed:.2f}s) print(f输出token: {resp.usage.completion_tokens}) print(fTPOT: {elapsed / resp.usage.completion_tokens:.4f}s)这段代码同时验证了接口连通性和基本性能。如果 TPOT 在 0.05s 以内说明解码速度不错如果超过 0.2s需要检查是不是max-num-seqs太小或者显存吃紧导致频繁换出。4.3 流式输出验证聊天场景通常要流式返回验证一下stream client.chat.completions.create( modelqwen2.5-7b, messages[{role: user, content: 数到10}], streamTrue ) first_token_time None start time.time() for chunk in stream: if chunk.choices[0].delta.content: if first_token_time is None: first_token_time time.time() - start print(chunk.choices[0].delta.content, end, flushTrue) print(f\nTTFT: {first_token_time:.3f}s)TTFT 是衡量预填充性能的关键。7B 模型在 1k 提示词下TTFT 通常在 0.1s 到 0.3s 之间。如果明显偏大检查提示词长度和max-num-batched-tokens设置。5. 本篇常见错误排查5.1 启动报显存不足报错信息通常是torch.cuda.OutOfMemoryError或No available memory for the cache blocks。解决顺序先把--gpu-memory-utilization从 0.92 降到 0.85再降--max-model-len比如从 16384 降到 8192还不行就上量化加--quantization awq或--quantization gptq但需要模型本身有量化权重。另外--max-num-seqs设太大也会在启动时预留过多 KV Cache可以先设 16 试。5.2 请求返回 404 或模型名不匹配客户端报model not found多半是--served-model-name和请求里的model字段不一致。用curl http://localhost:8000/v1/models可以列出当前服务注册的模型名照着填即可。如果返回 404 且路径没错检查 base_url 是否漏了/v1。5.3 并发一高就超时单请求正常、并发上来后大量超时通常是max-num-seqs太小导致请求排队或者客户端本身成了瓶颈。先用nvidia-smi -l 1观察 GPU 利用率如果利用率很低但请求堆积说明瓶颈在客户端 IO。可以换成 aiohttp 或 httpx 的异步客户端重测。如果 GPU 利用率高但吞吐上不去考虑开--enable-prefix-caching并适当增大max-num-batched-tokens。5.4 输出乱码或重复模型输出重复句子通常是解码策略问题。把temperature调到 0.7 到 0.9 之间加top_p0.9避免纯贪心解码。如果还是重复检查提示词里是不是有循环模式或者max_tokens设得过大导致模型“没话找话”。vLLM 支持repetition_penalty参数可以在请求体里加repetition_penalty: 1.1缓解。5.5 接入云端接口时的鉴权问题如果你在本地 vLLM 和 TaoToken 之间切换注意本地 api_key 填EMPTY即可云端必须填真实 Key。云端返回 401 时先确认 Key 没有多余空格再确认请求头是Authorization: Bearer key。接入文档里有完整的请求示例排障时可以对照检查。如果只是验证模型输出效果不想折腾本地部署直接用模型对话入口测试提示词确认效果后再决定是否本地化。6. 从跑通到用好下一步怎么走把服务跑起来只是第一步。接下来你可以做三件事一是压测用 vLLM 自带的benchmark_throughput.py测出当前配置的实际吞吐再针对性调参二是接网关把本地 vLLM 和云端接口统一到一个 base_url 后面按负载分流三是上量化如果显存紧张AWQ 或 GPTQ 能把 7B 模型压到 6GB 左右代价是少量精度损失。如果你打算长期做编码类或 Agent 类应用请求量大、上下文长可以考虑用 Coding Plan 管理调用配额和模型路由把本地推理和云端能力结合起来。本地负责低延迟、高频的短请求云端负责长上下文和复杂推理这样整体成本和体验都比较平衡。最后提醒一句vLLM 的版本迭代很快启动参数偶尔会变。遇到参数不识别时先python -m vllm.entrypoints.openai.api_server --help看当前版本支持哪些选项比翻旧文档靠谱。
返回列表