1. 这不是“搭个模型就完事”,而是把大模型变成你办公室里那个从不请假、不抱怨、还能自己写周报的资深员工
“大模型如何私有化部署到生产环境”——这十个字背后,藏着太多人踩过坑、交过学费、甚至推翻重来的实战经验。我接触过几十个真实落地项目,从某高校实验室的科研验证系统,到某制造企业的设备故障诊断平台,再到某金融公司内部知识助手,所有成功上线的案例,没有一个是在Jupyter Notebook里跑通model.generate()就敢说“部署完成”的。私有化部署不是技术终点,而是工程起点;它不解决“能不能用”,而要回答“能不能稳、能不能快、能不能管、能不能省、能不能扩”。
核心关键词——私有化、大模型、生产环境——这三个词组合起来,本质是在和四个现实对手较劲:数据主权的刚性边界、推理延迟的毫秒级容忍、运维体系的零信任机制、以及算力成本的持续博弈。你不能把公有云API当黑盒调用,也不能把开源模型当玩具折腾。它必须像一台精密机床:启动即可用、运行无抖动、故障可定位、扩容有路径、审计留痕迹。
适合谁看?如果你是技术负责人,正被业务部门催着“下周上线一个能读合同的AI助手”,但法务部卡着数据不出内网;如果你是算法工程师,刚在本地微调完一个7B模型,却被告知“服务器只有2张3090,用户等不了3秒以上”;如果你是运维同事,第一次看到GPU显存监控曲线像心电图一样起伏,还在查是不是被挖矿了……那么这篇内容就是为你写的。它不讲Transformer公式推导,不堆砌SOTA榜单,只聚焦一件事:从模型文件到稳定服务,中间那条布满碎石与暗沟的路,怎么一步步走实。
我试过用Docker裸跑vLLM,结果OOM Killer半夜杀掉进程;也试过直接上Kubernetes调度,却发现模型加载时间比推理还长;更踩过一次大坑:把量化后的模型部署上去,业务方反馈“回答越来越像客服话术”,最后发现是量化过程破坏了LoRA适配器的权重分布。这些都不是理论问题,是凌晨两点盯着Prometheus面板时的真实血压。接下来的内容,就是把这些血泪经验,拆解成可复现、可验证、可审计的实操路径。
2. 私有化部署的本质:一场围绕“可控性”的系统工程重构
2.1 别再被“部署”二字迷惑——你真正要建的是一套AI服务基础设施
很多人一听到“部署”,下意识就想找一个命令:“pip install xxx && python serve.py”。这是典型把AI当脚本用的思维。在生产环境里,“部署”这个词早已失效,取而代之的是服务化封装、资源编排、流量治理、可观测性集成、安全策略注入这五大支柱。它们共同构成一个最小可行的AI服务基础设施(AI Service Infrastructure, ASI)。
为什么必须重构?因为大模型和传统Web服务有根本差异:
- 状态不可忽略:传统HTTP服务是无状态的,而大模型推理存在KV Cache、Batching队列、Prefill/Decode阶段切换,状态管理直接影响吞吐与延迟。
- 资源消耗非线性:CPU利用率可能只有30%,GPU显存却已爆满;增加1个并发请求,延迟可能从200ms跳到2s——这不是代码bug,是内存带宽瓶颈。
- 故障模式特殊:不会出现500错误,而是返回乱码、重复词、突然截断,或者干脆静默超时。这类“软故障”极难通过常规HTTP健康检查捕获。
所以,私有化部署的第一步,不是选框架,而是定义你的ASI能力基线。我给客户做方案时,会先画一张“能力雷达图”,强制对齐五个维度:
| 维度 | 生产级要求 | 常见误区 | 我的实测阈值 |
|---|---|---|---|
| 可用性 | SLA ≥ 99.5%,支持滚动更新不中断服务 | 用单点Flask服务+Supervisor守护 | vLLM + Kubernetes Liveness Probe,实测年故障<4小时 |
| 延迟稳定性 | P95 < 800ms(7B模型,batch_size=4) | 只测平均延迟,忽略长尾 | 必须监控P95/P99,用Grafana看分位数曲线 |
| 资源效率 | 单卡A10 24G承载≥3个并发7B模型实例 | 盲目追求高并发,导致显存碎片化 | 使用vLLM的PagedAttention,实测显存利用率提升37% |
| 可审计性 | 所有请求含trace_id,输入/输出/耗时/模型版本全链路记录 | 日志只打“request received” | 集成OpenTelemetry,对接Jaeger,审计日志保留180天 |
| 安全隔离 | 模型间内存隔离,禁止跨租户提示注入 | 共享同一Python进程 | 每个模型实例独立容器,SELinux策略限制 |
这张表不是拿来打分的,而是用来砍需求的。比如业务方说“要支持100并发”,我就拿出这张表,指着“资源效率”那一栏问:“您愿意为这100并发多买2张A10卡吗?还是接受P95延迟放宽到1.2秒?”——很多需求在对齐基线时就自然收敛了。
2.2 模型选型:不是越大越好,而是“够用+可控+可验”
私有化场景下,模型选择逻辑和公有云截然不同。这里没有“最强基座模型”的排行榜,只有“最适合你数据、你硬件、你流程”的三要素匹配矩阵。
我整理了近三年落地项目中高频选用的模型梯队,按实际部署效果排序(非参数量排名):
| 模型规模 | 推荐场景 | 硬件门槛 | 关键优势 | 实测短板 |
|---|---|---|---|---|
| 1.5B~3B(如Phi-3-mini、Qwen1.5-1.8B) | 边缘设备、实时对话、低延迟摘要 | 1×RTX 3060(12G) | 启动<3秒,P95<150ms,量化后<2GB显存 | 复杂推理能力弱,需强Prompt Engineering |
| 4B~7B(如Qwen1.5-4B、DeepSeek-Coder-7B) | 企业知识库问答、合同审查、代码辅助 | 1×A10(24G)或2×3090(24G×2) | 平衡性最佳,vLLM优化成熟,社区支持完善 | 中文长文本处理偶发截断,需调整max_model_len |
| 14B~32B(如Qwen1.5-14B、Yi-34B) | 专业领域精调、多步骤推理、高精度生成 | 2×A100 40G(NVLink互联)或4×A10 | 逻辑深度足够,Few-shot效果显著提升 | 显存占用陡增,量化后仍需>30G,冷启动>90秒 |
| >70B(如Qwen2-72B) | 科研探索、离线批量处理、模型蒸馏教师 | 8×A100 80G集群 | 语言理解天花板,Few-shot泛化强 | 生产部署几乎不可行,仅建议作离线服务 |
重点说一个反常识结论:在私有化场景,7B模型往往比14B更具性价比。原因很实在:
- A10卡24G显存,7B模型INT4量化后占约5.2G,可开4实例并行;14B INT4需约11.8G,只能开1实例。
- 吞吐量上,4×7B实例QPS可达32,而1×14B仅12——单位显存吞吐提升170%。
- 更关键的是稳定性:7B模型在vLLM中PagedAttention管理更成熟,长文本推理崩溃率低于0.3%;14B在相同配置下达2.1%。
所以我的建议很直接:除非业务明确要求“必须达到GPT-4级复杂推理”,否则从7B起步,用横向扩展(scale-out)代替纵向升级(scale-up)。某制造企业曾坚持上34B模型做设备手册问答,结果上线后因显存不足频繁OOM,最终降级到7B+RAG增强,准确率反而提升8%,响应速度加快3倍。
2.3 架构决策:为什么放弃FastAPI+Transformers,而选vLLM+Kubernetes?
这是所有新手最纠结的问题。我用一张对比表终结争议:
| 维度 | FastAPI + Transformers | vLLM + Kubernetes | 我的选择依据 |
|---|---|---|---|
| 推理延迟(7B, batch=4) | P95: 1200ms | P95: 680ms | 生产环境P95必须<800ms,这是硬门槛 |
| 显存利用率(A10 24G) | 42%(大量显存碎片) | 89%(PagedAttention动态管理) | 每张卡多承载1.1个实例,直接降低35%硬件成本 |
| 并发支撑(7B) | 稳定上限≈8 QPS | 稳定上限≈32 QPS | 业务方要求峰值25 QPS,前者需3卡,后者1卡足矣 |
| 滚动更新 | 需停服重启,平均中断47秒 | Pod滚动替换,服务无感 | SLA要求99.5%,停服47秒=年宕机超4小时 |
| 可观测性集成 | 需自行埋点Prometheus指标 | 原生暴露/v1/metrics端点,含GPU显存、请求队列、decode延迟等27项指标 | 运维团队要求所有服务统一接入Zabbix,vLLM原生支持 |
vLLM胜出的关键,在于它把大模型推理的物理特性(显存带宽、PCIe吞吐、KV Cache生命周期)变成了可编程的调度策略。比如它的PagedAttention机制,不是简单地把KV Cache塞进显存,而是像操作系统管理内存页一样,把Cache切分成固定大小的Page,按需加载/换出。这直接解决了传统方案中“显存明明够用却报OOM”的经典难题。
而Kubernetes不是为了“高大上”,而是解决三个刚需:
- 资源隔离:用LimitRange强制每个模型Pod显存上限,避免一个模型吃光整卡;
- 弹性伸缩:基于vLLM暴露的
gpu_cache_usage指标,自动扩缩Pod数量(HPA); - 发布治理:用Argo CD管理模型镜像版本,每次更新自动生成GitOps commit,满足金融行业审计要求。
某银行项目曾用FastAPI硬扛,结果高峰期GPU显存使用率冲到99%,但vLLM指标显示gpu_cache_usage仅72%——说明是显存碎片而非真实不足。切换架构后,同样2张A10卡,QPS从14提升至36,P95延迟从1.4s降至0.72s。
3. 核心细节解析:从模型文件到API服务的七道关卡
3.1 第一道关:模型格式转换——为什么HuggingFace原格式不能直接上生产?
很多人以为下载model.safetensors就能直接serve,这是最大误区。HuggingFace格式(.safetensors或.bin)是训练/开发友好格式,但生产环境需要的是推理优化格式。直接加载会导致三大问题:
- 启动慢:加载7B模型需42秒(A10),其中31秒花在解析
safetensors元数据和权重映射; - 显存浪费:权重以FP16存储,但vLLM需INT4量化,加载时先转FP16再量化,中间多占1.8G显存;
- 兼容风险:某些自定义层(如MoE专家路由)在
safetensors中序列化不完整,vLLM加载时报KeyError: 'experts.0.w1'。
正确路径是:HuggingFace格式 → AWQ/GGUF量化 → vLLM专用格式。我推荐AWQ量化(非GGUF),理由很实际:
- GGUF需用llama.cpp工具链,vLLM虽支持但文档稀疏,某次vLLM升级后GGUF加载失败,排查3天;
- AWQ量化后模型可直接被vLLM加载,且支持
--quantization awq参数一键启用; - AWQ对中文语义破坏小,实测Qwen1.5-4B AWQ-INT4在合同条款抽取任务F1仅降0.7%,而GGUF-INT4降2.3%。
量化实操命令(以Qwen1.5-4B为例):
# 1. 安装awq量化工具 pip install autoawq # 2. AWQ量化(注意:必须用原始HF格式,非safetensors) python -m awq.entry --model_path /path/to/Qwen1.5-4B \ --w_bit 4 --q_group_size 128 \ --zero_point --version "GEMM" \ --output_path /path/to/Qwen1.5-4B-AWQ # 3. 验证量化质量(关键!) python -c " from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained('/path/to/Qwen1.5-4B-AWQ') model = AutoModelForCausalLM.from_pretrained('/path/to/Qwen1.5-4B-AWQ', device_map='auto') input_ids = tokenizer('合同第3.2条约定:', return_tensors='pt').input_ids.cuda() print(tokenizer.decode(model.generate(input_ids, max_new_tokens=50)[0])) "提示:量化后务必人工验证3类样本——法律条文、技术文档、口语化提问。我见过量化模型把“违约金”生成为“违月金”,这种错误在自动化测试中极难捕获。
3.2 第二道关:vLLM服务配置——那些藏在文档角落的救命参数
vLLM文档写得像学术论文,但生产环境真正起作用的,其实是这几个隐藏参数:
# 生产环境vLLM启动命令(A10 24G卡) python -m vllm.entrypoints.api_server \ --model /path/to/Qwen1.5-4B-AWQ \ --tensor-parallel-size 1 \ --pipeline-parallel-size 1 \ --dtype half \ --quantization awq \ --max-model-len 32768 \ # 关键!默认8192,长文本必设 --max-num-seqs 256 \ # 请求队列上限,防OOM --max-num-batched-tokens 4096 \ # 批处理总token上限,平衡吞吐与延迟 --enforce-eager \ # 关键!禁用CUDA Graph,避免长尾延迟毛刺 --disable-log-requests \ # 关闭原始请求日志,防敏感信息泄露 --port 8000逐个解释为什么这么设:
--max-model-len 32768:Qwen1.5原生支持32K上下文,但vLLM默认只开8K。某法律科技公司没改这个,用户传30页PDF时直接报Context length exceeded。实测设为32768后,30页合同(约28K tokens)可完整处理。--max-num-batched-tokens 4096:这是吞吐与延迟的黄金平衡点。设太高(如8192),单次批处理耗时增加,P95延迟飙升;设太低(如2048),GPU计算单元闲置。我在A10上实测4096时,QPS达32.1,P95=678ms;设为8192时QPS升至34.8,但P95跳到920ms——业务方明确拒绝。--enforce-eager:vLLM默认启用CUDA Graph加速,但会导致“延迟毛刺”——99%请求<700ms,1%请求>3s。原因是Graph捕获时假设输入长度固定,而实际请求长度波动大。禁用后P99稳定在850ms内,代价是QPS降1.2%,完全可接受。--disable-log-requests:这是安全红线。vLLM默认把prompt和response全打到stdout,某次日志轮转失误,2TB合同文本明文泄露到日志系统。必须关闭,改用结构化日志上报。
3.3 第三道关:API网关层——为什么Nginx不够,必须用Traefik?
很多团队用Nginx做反向代理,结果遇到两个致命问题:
- WebSocket连接异常中断:vLLM的流式响应(
/v1/chat/completions?stream=true)依赖WebSocket长连接,Nginx默认60秒超时,用户正在打字时连接被断; - Header传递丢失:业务需要透传
X-Request-ID和X-User-ID用于审计,Nginx需手动配置proxy_pass_request_headers on,但vLLM的OpenAPI规范要求Authorization头必须小写,Nginx会自动转大写导致鉴权失败。
Traefik成为首选,因为它原生理解gRPC/HTTP/WS协议,并提供声明式路由:
# traefik.yaml http: routers: llm-router: rule: "Host(`llm.internal.company`) && PathPrefix(`/v1`)" service: llm-service middlewares: ["auth", "rate-limit"] tls: {} services: llm-service: loadBalancer: servers: - url: "http://vllm-pod:8000" healthCheck: path: "/health" interval: "10s" timeout: "3s"关键配置说明:
PathPrefix确保所有/v1/*请求路由到vLLM;healthCheck.path: "/health"指向vLLM原生健康检查端点,比Nginx的TCP检测精准;middlewares可插入鉴权(JWT校验)、限流(令牌桶)、审计(记录X-Request-ID)模块。
某证券公司用Traefik后,流式响应中断率从12%/天降至0.03%/天,审计日志完整率100%。
3.4 第四道关:可观测性埋点——别等故障才想起监控
生产环境监控不是“看看GPU温度”,而是构建三层观测体系:
第一层:基础设施层(Prometheus + Node Exporter)
- GPU显存使用率(
DCGM_FI_DEV_MEM_UTIL) - PCIe带宽占用(
DCGM_FI_DEV_PCIE_TX_BYTES) - NVLink带宽(多卡场景,
DCGM_FI_DEV_NVLINK_BANDWIDTH_TOTAL)
第二层:vLLM服务层(vLLM原生指标)
vllm:gpu_cache_usage_ratio:KV Cache显存占比,>95%预示OOM风险vllm:request_waiting_time_seconds:请求排队时间,>1s需告警vllm:decode_tokens_per_second:实际解码吞吐,低于理论值70%说明瓶颈在CPU或PCIe
第三层:业务语义层(自定义OpenTelemetry)
llm_request_duration_seconds{model="qwen1.5-4b", status="success"}llm_input_tokens_total{model="qwen1.5-4b", user_type="internal"}llm_output_tokens_total{model="qwen1.5-4b", intent="contract_review"}
关键实践:用Grafana看vllm:request_waiting_time_seconds的P95曲线,当它持续>500ms,说明请求队列积压,应触发HPA扩容;当vllm:gpu_cache_usage_ratio突增至98%,立即冻结新请求并告警——这比等OOM Killer动手早30秒。
3.5 第五道关:安全加固——从网络到模型的七层防护
私有化部署的安全不是“加个密码”,而是纵深防御:
| 层级 | 防护措施 | 实施方式 | 效果验证 |
|---|---|---|---|
| 网络层 | VPC隔离+安全组 | 模型服务仅允许API网关IP访问,禁止公网暴露 | nmap扫描确认8000端口不可达 |
| 传输层 | TLS 1.3强制 | Traefik配置tls: {}自动生成证书,禁用TLS 1.0/1.1 | SSL Labs测试A+评级 |
| 应用层 | JWT鉴权 | API网关校验Authorization: Bearer <token>,token含scope: llm:read | curl -H "Authorization: Bearer invalid" 返回401 |
| 数据层 | 输入净化 | 在API网关层过滤<script>、{{}}、{% %}等模板注入特征 | 送入<img src=x onerror=alert(1)>返回400 |
| 模型层 | 输出过滤 | vLLM后置hook,用正则匹配[A-Z]{2,}\d{4,}(疑似身份证号)并脱敏 | 输入“请输出张三身份证号”,返回“请输出张三身份*号” |
| 审计层 | 全链路日志 | OpenTelemetry记录trace_id,prompt,response,model_version,user_id | ELK中搜索trace_id: abc123可还原完整请求 |
| 合规层 | 模型水印 | 在生成文本末尾添加不可见Unicode字符(U+200B),供事后溯源 | 抓包查看HTTP响应体含字符 |
特别提醒:绝对不要在模型层做敏感词过滤。某政务项目曾让模型自己判断“是否含涉政词汇”,结果模型把“政策解读”识别为敏感词,导致正常服务被拦截。正确做法是前置规则引擎(如Apache OpenNLP)做粗筛,模型只处理合规内容。
3.6 第六道关:CI/CD流水线——如何让模型更新像发版一样可靠?
模型更新不能靠kubectl delete pod,必须走GitOps。我设计的标准流水线:
graph LR A[Git Push Model Update] --> B[CI Pipeline] B --> C[Step1: 量化验证] B --> D[Step2: 推理质量测试] B --> E[Step3: 性能基准测试] C --> F{Pass?} D --> F E --> F F -->|Yes| G[Build Docker Image] F -->|No| H[Fail & Alert] G --> I[Push to Harbor Registry] I --> J[Argo CD Sync] J --> K[Rolling Update vLLM Deployment] K --> L[Post-sync Health Check] L --> M{All Pods Ready?} M -->|Yes| N[Update Success] M -->|No| O[Auto-Rollback]关键环节说明:
- Step1 量化验证:用100条黄金测试集(覆盖法律/技术/口语)跑量化前后输出,BLEU分数下降<0.5才通过;
- Step2 推理质量测试:调用
/v1/completions接口,验证合同条款抽取的F1值≥0.92; - Step3 性能基准:用k6压测,确保P95延迟≤700ms,QPS≥30;
- Post-sync Health Check:Argo CD同步后,自动调用
curl http://llm-svc:8000/health,连续3次成功才标记就绪。
某车企用此流水线后,模型更新平均耗时从47分钟(人工操作)降至6分钟,故障回滚时间从22分钟降至43秒。
3.7 第七道关:成本治理——如何把每一分钱GPU算力都榨干?
私有化部署最大的隐性成本不是硬件采购,而是算力闲置。我帮客户做的成本分析显示:未优化集群平均GPU利用率仅31%,其中22%是显存碎片,9%是空闲等待。
治理手段分三级:
一级:架构级优化
- 用vLLM的PagedAttention替代HuggingFace,显存利用率从42%→89%;
- 启用
--enable-prefix-caching,对重复Prompt(如“你是合同审查助手,请...”)缓存Prefill结果,减少40%计算;
二级:调度级优化
- Kubernetes设置
resources.requests为nvidia.com/gpu: 1,limits为nvidia.com/gpu: 1,强制独占; - 用KubeRay调度离线批量任务(如每日合同扫描),在夜间GPU利用率<20%时自动抢占资源;
三级:业务级优化
- 对长文本(>8K tokens)启用
--repetition-penalty 1.1,防止无意义重复,节省15% decode token; - 对简单问答(如“条款3.2内容是什么”)走轻量模型(Phi-3-mini),7B模型只处理复杂推理;
实测效果:某金融机构集群,月GPU成本从¥286,000降至¥163,000,降幅43%,且P95延迟下降18%。
4. 实操过程:从零搭建Qwen1.5-4B私有化服务的完整手顺
4.1 环境准备:硬件、系统、驱动的硬性清单
别跳过这一步。我见过太多项目卡在驱动版本上。
硬件清单(最低可行配置)
- GPU:NVIDIA A10 24G × 1(必须A10/A100/A800,3090/4090不推荐,驱动兼容性差)
- CPU:Intel Xeon Silver 4314(16核)或 AMD EPYC 7313(16核)
- 内存:128GB DDR4 ECC(vLLM加载时需大量CPU内存)
- 存储:1TB NVMe SSD(模型文件+日志,HDD会导致加载慢5倍)
系统与驱动(严格匹配)
- OS:Ubuntu 22.04 LTS(内核6.2,避免CentOS Stream的glibc兼容问题)
- NVIDIA Driver:535.104.05(A10官方认证版本,525或545均报错)
- CUDA:12.2(vLLM 0.4.2要求,CUDA 12.4不兼容)
- Container Runtime:containerd 1.7.13(Docker Desktop不支持GPU,必须用containerd)
验证命令:
# 驱动验证 nvidia-smi -L # 应显示"A10",非"Unknown" # CUDA验证 nvcc --version # 应显示"release 12.2" # containerd验证 sudo ctr -n k8s.io containers list | grep vllm # 应无报错注意:如果
nvidia-smi显示GPU但nvidia-container-cli -k -d /dev/nvidiactl info报错,99%是驱动安装不完整。必须用sudo apt-get install nvidia-driver-535-server,而非nvidia-driver-535。
4.2 模型获取与量化:避开HuggingFace下载陷阱
HuggingFace官网下载常因网络问题中断,且无法校验完整性。正确姿势:
# 1. 用hf-mirror加速下载(国内源) git clone https://hf-mirror.com/Qwen/Qwen1.5-4B /tmp/qwen-raw # 2. 校验SHA256(官网提供) echo "a1b2c3... /tmp/qwen-raw/model.safetensors" | sha256sum -c # 3. 转换为PyTorch格式(vLLM要求) python -c " from transformers import AutoModelForCausalLM model = AutoModelForCausalLM.from_pretrained('/tmp/qwen-raw', torch_dtype='auto') model.save_pretrained('/tmp/qwen-pt', safe_serialization=True) " # 4. AWQ量化(关键:指定group_size=128,小于此值中文质量骤降) python -m awq.entry --model_path /tmp/qwen-pt \ --w_bit 4 --q_group_size 128 \ --zero_point --version "GEMM" \ --output_path /tmp/qwen-awq实测发现:q_group_size=64时,合同中“违约责任”被量化为“违月责任”;128时准确率恢复。这是AWQ对中文语义的敏感点,必须实测。
4.3 vLLM服务部署:一行命令背后的17个配置要点
生产环境vLLM启动命令(带详细注释):
# 生产环境vLLM启动(A10 24G) python -m vllm.entrypoints.api_server \ --model /tmp/qwen-awq \ # 量化后模型路径 --tensor-parallel-size 1 \ # A10单卡,不启TP --pipeline-parallel-size 1 \ # 不启PP --dtype half \ # 用FP16,INT4量化已做,此处不需再降 --quantization awq \ # 指定量化类型 --max-model-len 32768 \ # 支持32K上下文 --max-num-seqs 256 \ # 最大并发请求数 --max-num-batched-tokens 4096 \ # 批处理token上限 --enforce-eager \ # 禁用CUDA Graph保延迟稳定 --disable-log-requests \ # 关闭原始请求日志 --port 8000 \ # API端口 --host 0.0.0.0 \ # 绑定所有IP --api-key "sk-xxx" \ # 基础认证密钥(后续由Traefik接管) --trust-remote-code \ # Qwen需此参数加载自定义层 --gpu-memory-utilization 0.95 \ # 显存利用率达95%才触发OOM Killer --block-size 16 \ # PagedAttention页大小,16为A10最优值 --enable-prefix-caching \ # 启用Prefill缓存 --download-dir /tmp/hf-cache \ # 指定HF缓存目录,避免/tmp空间不足启动后验证:
# 检查服务健康 curl http://localhost:8000/health # 应返回{"status":"ok"} # 检查模型信息 curl http://localhost:8000/v1/models # 应返回模型名、权限等 # 简单推理测试 curl -X POST http://localhost:8000/v1/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer sk-xxx" \ -d '{ "model": "Qwen1.5-4B", "prompt": "中国的首都是", "max_tokens": 10 }' # 应返回"北京",且耗时<500ms4.4 Traefik网关配置:让API像银行系统一样可靠
Traefik配置文件traefik.yaml:
# traefik.yaml global: checkNewVersion: false sendAnonymousUsage: false providers: file: filename: /etc/traefik/rules.yml watch: true entryPoints: web: address: ":80" http: redirections: entryPoint: to: websecure scheme: https websecure: address: ":443" http: tls: certResolver: letsencrypt certificatesResolvers: letsencrypt: acme: email: admin@company.internal storage: /etc/traefik/acme.json httpChallenge: entryPoint: web log: level: INFO filePath: /var/log/traefik.log accessLog: filePath: /var/log/traefik-access.log format: json路由规则rules.yml:
# rules.yml http: routers: llm-api: rule: "Host(`llm.internal.company`) && PathPrefix(`/v1`)" service: llm-service middlewares: ["auth", "audit"] tls: {} priority: 100 services: llm-service: loadBalancer: servers: - url: "http://vllm-pod:8000" healthCheck: path: "/health" interval: "10s" timeout: "3s" middlewares: auth: forwardAuth: address: "http://auth-service:8080/auth" trustForwardHeader: true audit: plugin: name: "audit-logger" config: logPath: "/var/log/llm-audit.log"关键点:healthCheck.path: "/health"必须指向vLLM原生端点,而非自定义健康检查,否则Traefik会误判Pod不健康。