从传统IT转行LLM Infra:GPU推理、vLLM与RAG落地的完整避坑指南

发布时间:2026/11/2 12:12:16
从传统IT转行LLM Infra:GPU推理、vLLM与RAG落地的完整避坑指南

离开TCS之后,我花了三个月才敢跟别人说自己干的是LLM Infra。不是因为怕露怯,而是这个领域跟过去在传统IT服务公司做企业交付完全不是一个物种。上篇写了为什么走、走之前准备了什么,这篇就说说真正落地后的日子:从第一天面对满机柜的NVIDIA GPU,到把第一个大模型推理服务稳定跑上生产,中间踩过太多坑,也终于开始理解“Infra”这个词的分量。这篇内容主要写给两种人:一是还在传统IT/外包/服务型公司写业务代码、想转LLM基础设施的人;二是已经入行但被GPU集群和推理服务搞到怀疑人生的工程师。相信我,你遇到的很多问题,不是你笨,而是这个领域有太多“没写在文档里的规则”。

1. 转行后的新战场:LLM Infra到底在做什么

1.1 从“写业务代码”到“伺候GPU”:工作内容的巨变

在TCS那几年,我干的是Java后端、Oracle数据库、数据迁移这类活。每天跟项目经理对齐需求,再跟客户开会确认验收标准,代码写得再烂,只要UT覆盖上去、SIT过了,系统就能上线。但是到了LLM Infra之后,我发现“上线”这个概念变了。模型推理服务没有一个人敢拍胸脯说“肯定没问题”,因为它的表现不仅取决于代码,还取决于显存余量、并发请求形态、调度器队列、甚至同一批GPU上其他租户的“邻居效应”。换句话说,传统服务主要靠CPU和内存,你用jstack能排线程阻塞;而LLM服务主要靠显存和算力,一个问题可能同时涉及CUDA、cuBLAS、NCCL、FlashAttention和K8s调度。

工作内容也彻底变了。以前我写代码是给业务逻辑服务,现在写代码是给模型“搭舞台”:写Prometheus指标、调Grafana面板、调vLLM的调度参数、给Triton写模型配置文件、观察NVIDIA DCGM exporter的GPU利用率。刚开始非常不习惯,总觉得这不是“开发”。但时间久了就明白,LLM Infra的本质就是把“用一个模型”变成“稳定、高效、便宜地用好一群模型”。这里面没有一个环节是纯业务逻辑,但每个环节都在影响业务。

如果你也是从传统IT转过来,先做好心理建设:你过去引以为傲的“设计模式”“事务一致性”“代码规范”在这里依然有意义,但不构成核心竞争力。核心竞争力变成了三块:对GPU计算原理的理解、对模型服务化工具链的熟练程度、对分布式系统排队与容错的直觉。这三块没有一样能从速成训练班里拿到,只能靠实打实地观察指标、读日志、啃Profiling结果。

1.2 团队分工:Infra与模型层、应用层的边界

LLM Infra这个岗位在不同公司其实差别巨大。有的公司叫ML Platform组,有的叫AIScale,还有的干脆挂在SRE下面。我现在的团队大约十个人,分工大致是:模型组负责训练和微调,算法组负责Prompt工程、评测和Agent流程,而我们Infra组负责把所有模型变成可以被上层以HTTP/gRPC调用的服务,同时保证延迟、吞吐、性价比。听起来很简单的“变身”过程,实际涉及镜像、调度、网关、缓存、批处理、容灾、回滚,比传统服务的复杂度高一个量级。

边界问题特别重要。模型组常常丢给我们一个HF权重目录就完事,算法组提的需求经常是“让这个模型支持流式输出且首Token时间小于200ms”。这些需求落到Infra组,就意味着我们要自己去决定:用vLLM还是TensorRT-LLM,要不要做PagedAttention,需不需要加LoRA adapter热加载,要不要在网关层做语义缓存,是否需要独立部署一个小的embedding模型做路由。这类决策不能全听上层的,Infra得有自己的一套方法论。后来我总结出一个原则:只要是关于“算力资源的分配和隔离”的问题,Infra必须有一票否决权;而只要是关于“模型效果”的问题,Infra可以给建议但不要越权。这个边界守住了,协作才会顺。

2. 核心方向拆解:我进入LLM Infra后最先啃的几块硬骨头

2.1 推理服务化:从HuggingFace接口到vLLM/TensorRT-LLM

刚转行那会儿,我以为把模型部署就是拿HuggingFace的pipeline起一个FastAPI服务。后来发现,那只适合Demo,根本扛不住生产。原因很简单:Transformer解码是自回归的,每个Token生成都依赖之前生成的Token,所以并发请求一多,如果是朴素的逐个生成,GPU利用率极低,显存也浪费在预分配上。vLLM出现以后,靠着PagedAttention把KV Cache分页管理,显存利用率大幅提升,又靠Continuous Batching把不同请求的动态生成过程塞进同一个Step,吞吐量能比朴素方案高出几十倍。

我做推理服务化时,第一版直接用了vLLM的OpenAI兼容接口,跑起来很爽,但后来发现高并发下偶尔会报CUDA OOM,或者出现请求被拒绝之类的问题。查了半天才明白,vLLM的max_num_seqs、gpu_memory_utilization、max_model_len这些参数之间的关系不是孤立的。GPU显存是硬约束,你要在“能给多少给KV Cache”和“留多少给激活值”之间腾挪。比如一张80GB的A100,跑7B模型,max_model_len设4096时,gpu_memory_utilization可以调到0.9;但max_model_len拉到8192,KV Cache占用会猛增,必须把gpu_memory_utilization降到0.85甚至0.8,否则同一时刻的并发序列数max_num_seqs就上不去。

后来也试过TensorRT-LLM,它的延迟确实更低,但构建Engine的过程比较劝退,每次改模型结构或者换精度都得重新转ONNX再编译。而且TensorRT-LLM对动态形状的支持不如vLLM灵活,业务上如果经常出现长尾长度请求,还是要做很多额外配置。所以我的经验是:中小团队做快速上线的私有化服务,vLLM是首选;如果模型固定、流量稳定、并且对延迟极度敏感,才值得用TensorRT-LLM那套流程打磨。至于ONNX部署LLM,我个人的看法是,它更多适用于边缘设备或对算子兼容性有特殊要求的场景,在数据中心GPU集群里,ONNX Runtime那套生态对最新模型的支持往往滞后,别为了“通用”而牺牲性能。

这里还要补一个容易被忽视的点:LLM当然属于深度学习,但Infra的视角跟算法不一样。算法关心模型结构改哪里效果更好,我们关心的是Attention计算到底把时间花在PreFill还是Decode上。如果是PreFill阶段(处理进来的Prompt)太慢,通常是计算密集,需要调大并行度;如果是Decode阶段(逐个吐Token)太慢,往往是显存带宽密集,此时加大Batch可能反而降低单Token延迟但提升吞吐。这是两个不同方向,很多新手混在一起调参,越调越糟。

2.2 网关与路由:当多个模型同时在线

LLM Infra不仅要做单模型服务,更多时候是面对一堆模型。内部可能同时跑着7B基座、13B指令微调版、32B的MoE、还有若干个embedding模型、reranker模型。如果把每个模型都直接暴露给调用方,调用方就要自己维护一堆endpoint,而且没法做负载均衡、权限控制、灰度。所以我们在服务层前面加了一个LLM网关,统一入口,根据路由规则把请求转发到对应的模型服务。

网关的选型有两种路径:一种是直接用现成的AI网关产品,比如LiteLLM Proxy、Portkey这些,开箱即用,支持OpenAI格式的转发、Key管理、模型别名。另一种是基于API网关二次开发,在Envoy或Kong上扩展,把模型服务的地址做成动态路由。我们最终选了LiteLLM Proxy做基础层,因为它天然支持几百种模型供应商的格式转换,比如把参数里max_tokens转成vLLM能认的max_tokens,把stop序列按模型要求转成不同字段,省了很多胶水代码。

但加了网关之后也会引入新问题,最典型的是超时和流式转发。由于LLM生成时间长,传统HTTP网关默认60秒超时根本不合适。我们需要为不同的模型路由单独配置读超时时间,以及处理流式传输时的Content-Type和缓冲问题。另外,网关最好能记录每一次请求的Token用量和延迟分布,因为这就是后续做成本核算和容量规划的基础数据。没有网关之前,我根本不知道谁在用我的模型、用了多少Token,上了网关之后才把账算清楚。

2.3 Token与上下文工程:重新理解Key/Query/Value

在传统IT里我从来没想过“Token”还有什么“三个点”。但是做LLM Infra之后,你必须对大语言模型内部的Attention机制有一个直觉层面的理解,因为很多调优参数跟它直接相关。我比较受用的一个类比是:Token之间的关系本质上像一场会议——Key标识每个人“我是什么背景”,Query表示“我在找什么信息”,Value则是“我能提供什么具体内容”。在Transformer的Self-Attention里,每个Token都会发出Query,去匹配其他Token的Key,最后加权取出对应的Value。模型在生成下一个Token时,就是在不断重复这个过程。

这个类比不是学术定义,但它能解释很多实际问题。比如为什么上下文越长,KV Cache越占显存?因为你要把每个Token的Key和Value缓存下来,供后续Query去匹配,Token多了缓存自然膨胀。为什么有些模型“填表”类任务表现差?因为Query不知道去哪个Key找答案,注意力分散了。搞明白这一点后,你在配置max_model_len、设置KV Cache量化、精简Prompt时就不会瞎调。另外,网上很多人讨论的“spatial LLM”或者“LLM ontology”,本质上也是在给模型的注意力提供更结构化的Key和Query——前者把空间位置信息编码进Token序列,后者把知识概念的关系显式定义出来,都是为了降低模型“大海捞针”的难度。

我还没到能设计模型内部结构的水平,但Infra的人至少要知道Token开销怎么算。一次请求的Token成本等于输入Token数加上输出Token数,很多排障场景里,你把输入里塞了一大堆无关历史,显存和延迟立刻上去,但效果并没有变好。所以我们在网关层加了“上下文压缩”策略,把历史消息做摘要压缩后再拼进Prompt,成本立刻下降了60%。这件事让我发现,Infra做事不是只看框架,而是要懂模型底层的计算逻辑。

2.4 RAG与GraphRAG落地中的Infra问题

RAG(检索增强生成)已经成了大模型落地最常见的方式。传统RAG流程是:文档切块、向量化、存入向量库、查询时召回TopK、拼进Prompt、再调用LLM生成。听起来很简单,但一旦放到真实业务里,问题全在Infra侧。

首先是向量化这一环,你要选embedding模型,还要决定用什么硬件跑。小模型可以跑在CPU上,但量大之后必须上GPU。其次,向量数据库选型也头疼:Milvus、Qdrant、pgvector、Elasticsearch各有各的适用场景,我们在自己环境里对比过,Milvus在千万级向量场景下的召回延迟和批量写入吞吐确实更强,但运维复杂度也更高。小规模直接上pgvector最省事,反正业务数据量不大,别为了“先进”而叠复杂度。

后来我们还做了GraphRAG的尝试,就是先抽取实体和关系,构建知识图谱,再结合图谱检索和文本检索一起喂给LLM。效果在某些特定业务上确实比纯向量检索好,尤其是需要多跳推理的问题。但GraphRAG的落地成本也高:实体抽取本身就要跑LLM任务,需要额外的GPU资源;图谱构建、存储、查询链路的开发维护都更复杂。作为Infra,你不但要评估模型效果,还要评估每一个功能模块的资源消耗。我记得早期我们上线GraphRAG时,实体抽取服务把一群V100的利用率拉满,结果主问答服务反而被挤得超时。后来把抽取任务改成异步批量,错峰调度,才解决。

3. 实操过程与关键配置:一次典型的大模型服务上线

3.1 需求场景与架构选型

我拿一个真实项目来复盘。当时业务方要一个私有化部署的“知识库问答”服务,数据是几千份内部技术文档,用户通过网页提问,系统返回带引用的答案。数据量不算大,但要求不能出公网,所以只能用自己的GPU集群。最开始他们想得很简单:在笔记本上跑个LangChain调用本地模型就行。但我们评估后否决了,因为用户量会有波动,而且模型服务不能和业务进程抢资源。

最终我们定的架构是:K8s集群上部署三个关键组件——vLLM服务跑13B的Chat模型(后面换成7B Qwen,为了成本)、embedding服务跑bge-large、以及一个基于FastAPI的RAG应用。RAG应用负责切块、召回、拼Prompt;vLLM服务由K8s Deployment管理,配HPA(KEDA)根据GPU指标自动扩缩容;前面挂LiteLLM Proxy做统一入口和Token计量。向量库用的pgvector,因为它可以跟业务库放一起,运维省心。

为什么这样选?因为这套组合最大程度兼顾了灵活性和可控性。vLLM负责最核心的生成性能;pgvector省掉一个独立的向量数据库;KEDA按请求队列长度或GPU利用率扩缩容,比固定副本数更省钱。要注意的是,K8s调度GPU的时候要提前声明nvidia.com/gpu资源,而且不能用request/limit都写一样的,否则节点可能因为碎片化导致调度失败。这些都是传统Java服务转过来后特别容易忽略的点。

3.2 显存与并发参数计算

上线前要做容量规划,不能拍脑袋。我们当时只有4张A800 80GB显卡,其中2张留给模型服务,1张留给embedding,还有1张备用。以7B模型FP16为例,模型权重大约14GB;KV Cache需要多少?根据公式:每Token每层的KV Cache大小 = 2(K和V) × 层数 × 注意力头数 × 每头维度 × 字节数。7B模型如果32层、32个Query头、每头128维,那么每个Token的KV Cache大约为2 × 32 × 32 × 128 × 2(FP16) = 524,288字节,也就是0.5MB。如果max_model_len=4096,单序列最多占4096 × 0.5MB = 2GB。一张80GB的卡,模型权重14GB,预留激活值和运行时约8GB,那么可给KV Cache的显存大约58GB,最多能容纳约29个完整序列。但考虑到实际并发中很多请求的生成长度远小于4096,vLLM的PagedAttention按页分配,实际能支撑的并发会话数会更多。

因此我们把max_num_seqs设成64,gpu_memory_utilization设成0.9,max_model_len设成8192(因为有些问题要带很长的文档片段)。但这里有个坑:max_model_len设太长,单请求如果真用到8192,那并发上限立刻下降;如果业务中90%的请求Token总量在2000以内,建议max_model_len设4096就好,还可以省显存给更多并发。很多时候业务方并不清楚自己需要多少上下文,我们采用的是“先保守,再逐步放开”的策略。上线前先用压测工具模拟30路并发,观察显存峰值和P95延迟,如果连续跑一两个小时CUDA错误是0,再考虑调大参数。

3.3 部署步骤与配置示例

具体操作上,大概分以下几步:

第一步,构建模型镜像。我们直接使用vLLM官方镜像作为底座,把模型权重放到PVC里,启动命令指定--model路径、--tensor-parallel-size(我们单卡跑7B,所以设为1)、--max-model-len、--gpu-memory-utilization、--enforce-eager(调试时用,正式环境去掉)等参数。注意要用--served-model-name设定对外名字,否则网关那边会不认识。

第二步,部署vLLM Deployment,关键片段大概长这样(简化):

apiVersion: apps/v1 kind: Deployment metadata: name: vllm-7b spec: replicas: 1 template: spec: containers: - name: vllm image: vllm/vllm-openai:latest command: ["python3", "-m", "vllm.entrypoints.openai.api_server"] args: - --model - /models/Qwen2.5-7B-Instruct - --served-model-name - qwen7b - --max-model-len - "4096" - --gpu-memory-utilization - "0.9" - --max-num-seqs - "64" resources: limits: nvidia.com/gpu: "1" volumeMounts: - name: model mountPath: /models volumes: - name: model persistentVolumeClaim: claimName: model-pvc

这里尤其要注意:K8s的nvidia.com/gpu只能在limits里声明,不能放在requests里(新版本插件也支持request=limit,但容易引发调度问题)。另外,如果启动后vLLM报CUDA error: out of memory,先看是不是其他Pod占用显存,或者gpu_memory_utilization设得太高。我们的经验是留10%给CUDA context和碎片就够了,但如果有别的进程同卡跑,就必须调低。

第三步,部署embedding服务和RAG应用。embedding服务可以用TEI(Text Embeddings Inference)或者FastAPI + sentence-transformers。我们为了统一管理用了TEI,它原生支持动态批处理和显存优化。RAG应用用LangChain但只用它的Retriever部分,整个链路自己控制。

第四步,配置LiteLLM Proxy。在config.yaml里定义模型路由,把内部的vLLM endpoint和embedding endpoint映射成对外模型名,例如:

model_list: - model_name: qa-llm litellm_params: model: openai/qwen7b api_base: http://vllm-7b:8000/v1 api_key: dummy - model_name: embed litellm_params: model: huggingface/bge-large api_base: http://embed:8080

这样上层只认识两个名字:qa-llm和embed。后续做灰度或者切换模型,只需在Proxy配置里改映射。

第五步,接入监控和压测。用Prometheus抓vLLM的/metrics(它会暴露gemm、cache等指标),再用Grafana画图。压测工具用的是自研脚本和Hey,模拟多并发请求。压测目标不是打满GPU,而是找到“延迟-吞吐”的甜点:P95首Token延迟小于500ms、每Token延迟小于40ms,同时GPU利用率稳定在70%~80%,不出现排队堆积。

3.4 现场实录:从压测到上线

第一次压测时,我们把并发拉到100,结果vLLM直接报错“Too many pending requests”。后来发现默认的max_num_seqs是256,但我们设置了64,按理说不应该。查日志才搞明白,网关和重试机制把请求打到了同一个Pod,而且一次性涌进来200个并发,超过了64。这里就体现出网关层限流的重要性。后来我们在LiteLLM Proxy里加了一组rate limit,按用户维度控制每秒请求数,同时调整了KEDA触发器,根据vLLM队列深度自动扩容,让积压请求分散到多个副本。

还有一次线上问题更典型:某天下午模型服务突然变慢,P99延迟飙到10秒以上。排查好久,发现是另一个团队在同一个K8s节点上跑了一个GPU密集型任务,虽然没有申请nvidia.com/gpu,但用了CUDA_VISIBLE_DEVICES=0直接访问显卡,导致显存被抢。这说明裸奔访问GPU是LLM Infra的大忌,后来我们给所有Pod都加了资源约束,并在节点上部署了DCGM Exporter,只要发现GPU显存使用率异常,就会告警。这类问题在传统服务里几乎没有,但在GPU集群里必须当成安全事件对待。

4. 常见问题与排查技巧实录

4.1 高频问题速查表

我把这段时间遇到的高频问题整理成一张速查表,大家可以对着处理:

症状可能原因处理方式
vLLM服务启动后立即CUDA OOMgpu_memory_utilization过高或其他进程占用显存查看nvidia-smi确认显存占用,下调utilization到0.85左右
请求返回超时后端排队过长或单请求生成长度太长检查网关超时配置,缩短max_model_len,或增大副本数
生成内容重复/空洞模型本身问题或解码参数设置不合理调高temperature,设置frequency_penalty,在网关层统一参数
长时间运行后吞吐下降KV Cache碎片化或节点温度导致降频重启Pod或调整调度策略,检查DCGM温度指标
请求被网关拒掉API Key错误或模型别名没映射先用curl直连vLLM确认,再查litellm配置
embedding召回效果差切块策略不合适或向量模型太弱对比不同chunk size,尝试换bge-m3或重排模型
多模型并发互相影响共享GPU但没做资源隔离使用MIG或为每个模型分配独立GPU,至少加显存限额
报“provider rejected the request schema or tool payload”传给模型的tools参数与后端模型格式不兼容检查工具定义里的JSON Schema,去掉特殊类型,或改用原生OpenAI格式

还有一些属于“看起来像模型问题,实际是Infra问题”的坑,比如换了NVIDIA驱动之后模型输出变成NaN,多半不是模型坏了,而是CUDA和PyTorch版本不匹配;比如某个GPU编号上的张量计算偶尔出错,跑自检正常但业务偶发异常,可能是指标卡或掉卡,需要看dmesg。这类问题只有长期接触Infra的人才会第一时间想到。

4.2 几个独家排障心得

第一,永远先看“排队”而不是“卡死”。LLM服务慢,80%是请求在排队,而不是模型卡死。你需要观察vLLM暴露的Waiting/Running序列数和平均生成速度。如果排队序列很长,扩容;如果Running序列很高但每个请求的生成速度很慢,可能GPU利用率不足或数据加载有瓶颈。别一上来就重启Pod,否则缓存丢了,反而更慢。

第二,日志要带request_id。传统系统里我们习惯在日志里打transactionId,在LLM Infra里更要强制要求。因为一个请求会经过网关、RAG应用、模型服务、向量库多个节点,没有request_id根本没法串联耗时。我们后来统一把request_id写到所有日志的structured字段里,并用Jaeger接了Trace,定位问题的时间从小时级降到分钟级。

第三,模型权重的加载和下载经常被忽略。第一次从HuggingFace拉模型权重时,如果网络不好,可能断断续续拉几十GB。到私有化环境里更是灾难。后来我都先把权重复制到本地NAS,再从NAS同步到GPU节点的本地SSD,同时用checksum校验。不要为了省事直接从对象存储读权重,否则启动时模型加载就能卡十分钟,而且一旦文件损坏,模型启动一半失败,排查起来极其费劲。

第四,和算法组协作时,要学会用“资源账本”说话。当算法组提了一个特别占资源的RAG方案或者非要上极大的模型时,不要只说“不行”,而是给出数字:这个模型需要多少卡、大概多少并发、每Token成本多少、如果要达标需要加几张卡。我发现自己转行后沟通方式变化很大——从讲道理变成讲“账”,效果反而很好。

第五,所有踩过的坑一定要沉淀到团队内部的LLM Wiki里。这个Wiki不是摆设,而是我们每周五复盘会的一个重要输入。无论是网关配置错误,还是某个参数导致显存暴涨,都记成“症状-原因-解法”三段式,后面遇到相似问题直接搜。几个月下来,这个Wiki已经成了团队里价值最高的知识资产。

5. 转行后的复盘:哪些认知必须重塑

5.1 从需求驱动到资源驱动

在TCS做交付,本质是需求驱动:客户要什么,我们就做什么,无非是多写几个接口。而LLM Infra是资源驱动:你手里的每一张GPU都在烧钱,你的核心职责不是满足所有请求,而是用有限算力服务更多高价值请求。怎么定义高价值?有些问题是低延迟高优先级的(比如在线对话),有些是异步低优先级的(比如批量文档抽取)。Infra要做的是给不同优先级设置不同的队列、不同的副本数、甚至不同的网关限流策略。这个转变一开始很难受,因为我总觉得拒绝需求就是能力不足。后来才明白,盲目满足需求,最后会造成集群爆炸,反而谁都服务不了。

资源驱动还意味着你要学会“预测未来”。比如大促或者新功能上线前,业务量可能翻倍。传统服务扩容只需要提前加机器,但GPU集群扩容涉及采购、装机、驱动、镜像同步,周期很长。所以要在业务发布前至少两周做容量评估和资源申请。这是跟传统IT完全不同的节奏感。

5.2 FinOps成本意识

我在TCS时也有成本概念,比如服务器数量、license费用。但LLM领域的成本模型完全不一样,它的核心是Token和GPU利用率。曾经我们有一个业务只调用模型做在线摘要,流量很小,但每次请求都带很长的上下文,算下来每千Token成本高到惊人。后来在网关层做了一个“上下文压缩”策略,把历史消息做摘要压缩后再拼进Prompt,成本立刻下降了60%。这件事让我发现,Infra不只是技术岗,还是半个财务岗。你要能看懂账单里的每一项,知道是哪条业务线哪个模型烧的钱,才能让老板心甘情愿地掏钱加卡。

还有一个通用经验:模型服务一定要做“按需冷热分离”。对频繁使用的核心模型,保持常驻Pod;对偶尔用到的辅助模型(比如用于评估的LLM as Judge),可以设置空闲自动缩容到0,等请求来了再拉起。虽然冷启动有几十秒延迟,但非实时场景完全能接受。这个策略在K8s上很容易实现,用KEDA的ScaledObject配合Cron触发器即可。有人总觉得自动缩容到0有风险,但实际部署后,月度GPU成本省了接近四成,这个诱惑力太大了。

5.3 保持对榜单和工具链的敏感

转行之后,我发现这个领域的信息更新速度比传统企业IT快一个数量级。昨天还在用LangChain,今天可能就出了新框架;前天还在用FP16,今天就有人推FP8甚至INT4量化。所以我养成一个习惯:每周花一点时间轮一遍Open LLM Leaderboard、HuggingFace Trending、各种高质量技术博客,不是为了赶时髦,而是为了不让自己手里的技术栈过早过时。

但另一方面,我也走过很多弯路。有一段时间我们疯狂追逐新框架,看到“spatial LLM”“LLM ontology”这些概念就想去试。后来发现,对Infra来说,把传统RAG的向量召回、重排序、上下文窗口管理做好,带来的收益远大于盲目上新奇特的技术。我的判断标准是:如果一项新技术无法在GPU利用率、延迟、成本、可维护性四个维度中至少改善两个,那就不适合上生产。这个标准帮我过滤掉了很多“看起来很美”的东西。

新工具链也要看生态和社区,不要只看Star数。比如当初我们在选LLM网关时,一度想自己基于FastAPI写一个,后来还是用了LiteLLM Proxy,原因是它社区活跃、已经兼容上千种模型供应商的格式差异。自己做看起来可控,但后续维护成本极高。Infra的价值在于“借力打力”,而不是什么都从零造轮子。

最后再分享一个团队内的小技巧:我们每周五会做一次“GPU账单复盘”,用一张表格列出每块卡在跑什么模型、利用率多少、产生了多少Token、对应业务收益是什么。这个习惯让我们慢慢形成了“算力如同预算”的文化。发现某块卡长期利用率低于10%,就主动关停或合并到其他服务,久而久之,整个集群的能效提升非常明显。这张表比任何高级监控面板都管用,也许你可以从下周开始也记录一下自己的算力账单。