一、先定清要交出去的四样东西
1. 模型本体:权重加结构描述
第一样是权重文件,以及说明这份权重该怎么读入的结构描述。两者必须放在一起:少了结构描述,接收方只能靠猜,猜错的表现往往是服务能起来但输出错乱,比直接报错更难查。
体积较大的模型通常会被切成多个分片上传,这时要额外给出一份清单:一共几片、每片多大、校验值多少。分片缺片的后果并非启动失败,而是读入后行为异常——这一条在实际故障里出现的频率不低。
2. 推理参数:决定答复形态的一组值
第二样是推理参数,包含采样方式、长度上限、停止条件、上下文窗口上限。这些值对应训练时的数据分布与任务形态,不能随手填。同一份权重,参数配错,答复会从“可用”变成“不太好用”,而使用方只会觉得模型不行。
参数里容易被忽略的是上下文窗口上限与并发上限这一对。两者的乘积不能超过为缓存预留的容量,否则日常正常、压力上来时溢出。这条约束要在交付时就写明,不能留给部署环节去试。
3. 接口契约:调用方要照着写代码的那份东西
第三样是接口契约:请求地址、鉴权方式、字段名与类型、必填与选填、返回结构、错误码含义。契约含糊,联调阶段就会变成一场反复对齐的反复沟通。
契约里有三处要写得格外具体:一是输入字段的类型,是纯文本还是结构化的多段内容;二是返回里结果字段的位置与形态;三是错误码的分类,让调用方能区分“是我传错了”和“你这边暂时不行”。
4. 部署说明:给运维看的那一页
第四样是一页部署说明:所需规格、依赖的外部服务、如何判断就绪、日志落在哪里。这页不必长,但要能回答一个问题——换人接手,能不能不问人就把服务拉起来。
二、上传前的三项准备
1. 先在本地把整条推理流程跑通
第一步是先在本地用与训练一致的预处理和后处理,拿一两个真实样本完整跑一遍,然后才上传。本地都跑不通,上传只会把问题放大,而且排查手段更少。
这一步要记录两件事:一份典型输入的原始形态,一份对应的期望输出。这两份样本在后面联调时是第一道比对基准。
2. 把输入输出定义写成表
把字段名、类型、取值范围、是否必填列成一张表,与调用方确认一遍再上传。这张表就是接口契约的底稿,改一次成本很低,上线之后再改要牵连调用方改代码。
3. 命名与版本号一次定好
建议按“模型名-用途标识-版本号”命名,版本号只增不改。同一份权重被反复覆盖是很多事故的起点:上一版出了问题想回退,发现已经被覆盖了。
三、上传与登记
1. 上传之后先校验,再登记
上传完成不等于文件可用。要做两件事:核对分片清单是否齐全,核对校验值与本地一致。校验不通过就重传,不要带着问题往下走。
2. 登记要带上四类信息
登记时把模型名、版本、结构描述、校验值一起记上,形成一个不可变的版本记录。这条记录是后面所有对账的依据:出问题时先看当时用的是哪个版本,而不是凭记忆。
3. 权限按用途分
谁能上传、谁能发布、谁能取回、谁能删除,四个动作分开授权。常见的问题是把上传权限和发布权限给到同一个人、同一个账号,于是测试中的半成品被直接推到了对外服务上。
四、服务创建与参数配置
1. 实例规格从够用起步
先用较小规格验证功能,确认服务能起来、结果正确,再按压测结果决定是否扩。一上手就选大规格,既浪费,也会掩盖模型本身的性能问题。
显存估算要按三块算:权重、缓存、运行余量。三块分开估,估完标注假设。常见的低估都出在缓存上——序列越长、并发越大,缓存增长越快。
2. 四项参数互相牵制
实例数决定并行请求路数,单实例显存决定能装多大的模型与多少缓存,批处理策略决定吞吐与单条延迟的取舍,超时设置决定异常请求会不会长期占住资源。
四项不能各调各的。批处理凑得越大,吞吐越高但首字延迟越长;实例数调高能缓解排队,但成本跟着上去。参数要贴着业务的真实形态定,不能照抄别人的配置表。
3. 三类探针分开设
启动探针管“起来了没有”,存活探针管“还活着没有”,就绪探针管“能不能接流量”。三个混成一个,常见后果是流量被打到还在读入权重的实例上,一批请求全部超时。
就绪探针尤其重要。没有它,扩容出来的新实例在准备好之前就会接到请求,用户看到的就是一片失败。
4. 网关超时要盖过响应耗时的上限
这一条常在联调阶段才被发现。推理服务处理长上下文请求可能需要几十秒,网关默认超时往往短于这个数字,表现是服务端日志正常、调用方一直收不到结果。
配置时先测出目标场景下响应耗时的上限量级,再把网关超时设在其之上,并留出余量。
五、接口联调的七个动作
1. 先验连通,不验内容
第一步只做一件事:从调用方所在的网络环境发起一次请求,确认地址可达、端口通、没有被中间层拦掉。内容对不对是下一步的事,两件事混在一起查,容易把网络问题误判成服务问题。
2. 再验鉴权
用正确的密钥发一次,用错误的密钥发一次,用失效的密钥再发一次。三次结果要能区分:正确时通过、错误时被明确拒绝、失效时提示重新获取,而不是一律报同一个错误。
3. 单条请求验返回结构
拿本地跑通时留下的那份样本,与线上返回逐字段比对。重点看三处:结果字段位置对不对、有没有多余的包装层、数值与单位是否一致。
4. 验流式输出
如果服务采用流式返回,要专门验三件事:分片是否按预期逐步到达、结束标志是否正确给出、中途断开时调用方能否识别。流式常出的问题是“看起来在流,其实攒完才发”,表现是首字延迟与整体延迟几乎相同。
5. 验异常路径
逐项制造:超长输入、空输入、含特殊字符的输入、超出长度上限的输出场景。每一项都要看服务给出的是可识别的错误,还是静默截断或者干脆断开。静默截断更麻烦,调用方会以为拿到了完整结果。
6. 压并发
按目标并发跑一轮,记录三个数:单实例稳定承担的路数、延迟分位值、失败率。均值在这里没有意义,被大量快请求拉低之后,掩盖的正是让用户抱怨的那部分慢请求。
7. 测长上下文
按业务里长度上限的输入再跑一轮。很多问题只在这一轮出现:显存吃紧到上限、延迟陡增、后段输出被截断。这一轮的数据是后面定容量与定超时的依据。
六、联调阶段常卡住的四处
1. 超时设置不匹配
前面提过,但值得再提一次。三层超时要逐个核对:调用方客户端、中间网关、服务本身。任何一层短于实际处理时长,都会表现为“偶发失败”,而且失败比例随输入变长而上升。
2. 字段类型不一致
调用方按文本传,服务按结构化内容解析;或者数值传成了字符串。这类问题的表现是请求被拒但错误提示含糊,两边各说各的对。
3. 返回结构版本漂移
服务升了版本,返回里多一个字段或少一层包装,调用方解析失败。契约里要写明“新增字段不影响解析、删改字段必须提前通知”这条规则。
4. 密钥与环境的对应关系乱了
测试环境的密钥被复制到正式环境,或者一个密钥被贴到了多个调用方那里。这会让用量无法归属,出问题时也判断不出是谁在调用。密钥按调用方分发,环境之间不复用。
七、上线前的验收与交接
1. 五份记录齐了才算交付
第一份是模型版本记录,含校验值;第二份是接口契约,含错误码表;第三份是联调记录,七个动作各自的结论;第四份是压测数据,含并发、延迟分位值、失败率;第五份是部署说明。五份齐了,后面换人接手才有依据。
2. 让一位没参与的人走一遍
交接前找一位没参与部署的同事,照契约和部署说明从零走一次:建服务、发请求、看结果。他卡住的地方,就是文档没写清的地方。改完,这条流程才算真的通。
结语
部署这件事,难点不在会不会操作,而在交付内容是否说清。四样东西——模型本体、推理参数、接口契约、部署说明——定了,后面每一步都有依据;上传校验、参数牵制、探针分层、超时匹配这几处把住了,联调就不会变成反复试错。
落地建议:先把四样东西写齐,再按“连通、鉴权、单条、流式、异常、并发、长上下文”七个动作联调一遍,最后补齐五份记录再放量。判断这套流程是否走通,标准很实际:把接口契约和部署说明交给一位没参与的同事,他不需要问人,就能把服务拉起来、把请求发通、把结果对上。