首页 / 资讯中心 / 文章详情

函数计算零配置部署Qwen3.5:大模型推理服务实践

函数计算零配置部署Qwen3.5:大模型推理服务实践 ★ FEATURED ARTICLE
直接写这样一个标题很多人的第一反应是“又是一个标题党”。但实话说我把Qwen3.5通过函数计算平台跑起来之后最大的感受是这个方案确实有资格用“零配置”这个词而且它解决的痛点非常具体——模型推理的部署成本、闲置浪费、弹性扩容问题。这篇文章我尽量把这套玩法的完整链路讲透为什么选函数计算、架构上怎么处理冷启动、参数怎么调、上线后怎么排查问题以及我实测下来的一些坑。先说清楚这玩意儿能干什么。你在本地用GPU调通了一个Qwen3.5的对话Demo接下来想让团队内部或者一个小范围用户群体能用上传统思路是租一台GPU云服务器装驱动、配CUDA、部署推理框架、写服务端代码、配监控告警……一套下来少说两天。而“零配置部署”的思路是把模型和推理代码打包进容器镜像推到函数计算平台的镜像仓库然后在控制台上传镜像、配几个环境变量、设置好内存和超时时间平台会自动帮你把服务拉起来并暴露一个HTTP端点给你调用。整个过程里你不用碰服务器不用管驱动甚至不用关心实例是怎么调度出来的。平台会在请求进来时自动拉起实例、加载模型、执行推理、返回结果请求结束后自动回收资源。适合谁来参考我建议这几类人可以重点看一下第一已经在本地或自建服务器上跑通了开源大模型想快速做一个对外可用的API服务的人第二业务流量有明显波峰波谷不想为闲置的GPU买单的团队第三想用极低门槛给客户演示“我有一个大模型驱动的智能助手”的独立开发者。如果你属于这几类这篇文章的实操部分可以直接照着抄。1. 为什么是“函数计算”而不是GPU服务器1.1 先算一笔账传统部署到底贵在哪我最早跑Qwen模型推理用的是自建GPU服务器。模型是量化后的版本单卡大概需要24GB显存左右。我当时租了一台带单卡的机器月租大几千这还只是硬件成本。更麻烦的是这个服务不是时时刻刻都有流量白天团队测试用得勤晚上和周末基本闲置。但服务器费用是按月包的闲置的算力等于白花钱。还有一个容易被忽略的开销——运维人力。GPU服务器的驱动版本和CUDA版本搞不好推理框架装不上推理进程OOM了没人看服务器磁盘满了没人清。这些事听起来小但每一项都会消耗一个开发者的半天时间。我在某个项目里就遇到过因为某次宿主机内核升级导致驱动失配整个推理服务挂了半天才被用户发现排查过程极其痛苦。函数计算平台的计费模式完全不一样。它是按实际请求处理时长 并发实例数计费的没有请求的时候实例缩容到零一分钱不花请求来了平台按需拉起实例处理完再缩掉。对于波峰波谷明显的场景这种模式的成本优势是数量级的。更重要的是驱动、CUDA、运行环境这些事被平台托管了你只需要在镜像里把推理环境装好剩下的调度和资源分配都是平台的事。1.2 函数计算的本质让“部署”变成“上传镜像”很多人对函数计算的理解还停留在“写几个函数处理小请求”的层面觉得它处理不了大模型这种重负载。这个观念得更新一下。现在的函数计算平台普遍支持自定义容器镜像也就是说你可以在本地把Python环境、依赖库、模型权重、推理服务代码全部打包进一个Docker镜像然后推到平台的镜像仓库。平台会以这个镜像为基础运行你的服务进程。这意味着什么呢意味着你在本地怎么跑推理在云上就怎么跑推理。本地调试时用GPU跑通的服务打包成镜像传到云端平台分配到GPU实例后行为和你本地环境几乎完全一致。这种模式大大降低了迁移成本也规避了“代码能跑、部署就挂”的经典问题。我选择函数计算还有一个考量弹性伸缩策略。GPU服务器的扩容是一个很痛苦的过程你需要在云平台手动购买新机器、装环境、部署服务、接入流量调度流程复杂且缓慢。函数计算平台可以配置一条策略——当在线实例的CPU或显存使用率超过某个阈值时自动增加并发实例数。整个扩容动作在几秒内完成而且是无感的用户请求会被自动分发到新实例上。1.3 使用场景边界不是所有模型都适合“零配置”这里我得泼一盆冷水。函数计算跑大模型虽然方便但并不是所有场景都适合。如果你的业务特点是长连接——比如用户需要保持一个WebSocket连接和模型进行多轮实时交互或者你的模型需要在多个请求之间保持对话状态那么函数计算的经典请求-响应模式可能就不太匹配因为函数实例随时可能被回收内存中的状态不会持久化。另外如果模型规模大到需要多卡并行推理——比如超过单卡显存上限比如加载一个百亿以上参数的非量化模型——函数计算平台的单实例配置可能不够用。虽然部分平台支持多卡实例但对绝大多数应用场景来说单卡甚至量化后的半精度单卡已经足够支撑Qwen3.5这类模型的中小并发使用。所以先明确自己的模型规模和并发预期再决定要不要用函数计算这是最实在的建议。2. 架构设计与冷启动攻坚2.1 整体架构从“模型文件”到“可调用API”的三层结构整个系统分三层来设计理解了这个分层后面的配置就不会乱。第一层模型与推理服务层。这是核心负责加载Qwen3.5的模型权重接收HTTP请求中的提示词执行推理返回文本结果。我会在FastAPI框架里实现一个简单的接口接收prompt和max_tokens参数调用模型生成回复。第二层函数计算平台层。平台负责管理实例的生命周期。收到请求后平台调度一个实例运行我们的推理服务进程处理完成后根据配置决定是否保留实例以应对后续请求。这一层的关键配置是实例并发度、闲置存活时间、超时时间下面会细说。第三层触发与访问层。函数计算平台会为服务生成一个HTTP访问端点你可以把它直接集成到Web应用、聊天机器人、自动化脚本里。平台自带的身份认证功能可以防止接口被恶意调用。这三层结构的好处是每一层都可以独立替换。比如后续你想升级模型版本只需要更新镜像里的模型文件重新推一个镜像版本无需改动任何平台配置你想迁移到别的计算平台运行修改的也只是平台层的配置核心推理代码完全不需要变动。2.2 冷启动最大的敌人以及我的应对方案大模型推理服务的最大技术挑战不是模型本身而是冷启动——从平台收到第一个请求到模型完成加载并开始推理这个过程需要多久。Qwen3.5这类模型的权重文件动辄几十GB即使在镜像里打好包加载到GPU显存也需要十几秒甚至更久。如果每个请求都从零开始加载模型那用户体验就是灾难——等待时间可能长达一分钟。我测试过的方案大体归为以下四类按优先级排序方案一实例预置预留模式。部分函数计算平台支持配置最小在线实例数。比如设置最小实例数为2平台会在服务创建后立刻拉起两个实例并提前加载模型常驻内存。请求进来时直接打到已就绪的实例上延迟可以控制在百毫秒级。代价是这两个实例即使没有请求也会持续计费本质上是用少量固定成本换取低延迟。我建议生产环境至少配置1个预置实例。方案二镜像内加载模型文件。平台在启动实例时镜像中的所有文件已经存在于本地磁盘不需要再从对象存储下载。这个方案的加载速度取决于镜像大小和平台拉取镜像的效率但无论如何都比运行时远程拉取快得多。需要注意的是一些平台的镜像大小限制可能需要把几十GB的模型文件打进镜像时要谨慎——这部分我后面实操节会讲具体怎么处理。方案三推理框架的延迟加载优化。使用支持流式加载的推理框架——比如在模型加载时采用分片读取、边加载边推理的方式——但实际应用中这种优化收益有限因为模型加载的瓶颈是显存带宽和权重文件读取速度。更有效的做法是让推理框架在第一次请求前完成模型加载也就是常说的“预热”。方案四利用平台的自定义健康检查。很多函数计算平台支持自定义健康检查探针平台会根据探针结果判断实例是否就绪。我把模型加载放在FastAPI的启动事件中这样实例进程启动后先加载模型加载完成才对外提供服务。配合探针机制平台只会把请求路由到已经完成模型加载的实例上避免用户请求打到正在加载中的实例。2.3 关键配置参数并发度、超时时间、环境变量几个核心参数我直接给出推荐配置同时解释一下为什么是这些值。实例并发度。单人单请求场景实例并发度设置为1最简单即一个实例同时处理一个请求。如果模型推理吞吐较高也可以适当提高并发度比如设置为4让一个实例同时处理多个推理请求。但要注意大模型推理是显存密集型和计算密集型的任务并发度过高会导致单个请求的响应时间大幅拉长。我的习惯是先设1测试稳定后再逐步上调。超时时间。Qwen3.5生成一段长文本可能需要几十秒超时时间设置太短会导致推理任务被平台强制中断。常规建议设置为300秒覆盖绝大多数场景。如果用户会生成极长的内容可以适当延长但要注意函数计算平台本身可能有最大超时上限。环境变量。一些关键配置尽量用环境变量传递而不是硬编码在代码里。比如模型路径、量化开关、日志级别、API密钥等。这样做的好处是后续调整参数时不需要重新构建镜像。3. 实操从本地Demo到云端API的完整部署3.1 准备工作与镜像打包这一步我们要准备Docker镜像。我假设你已经有一个跑通的Qwen3.5推理脚本如果没有下面这个最小示例可以参考。先创建一个项目目录结构如下project/ ├── app.py # FastAPI 推理服务 ├── requirements.txt # Python 依赖 └── Dockerfile # 镜像构建文件app.py的核心逻辑用transformers库加载模型定义POST接口/v1/chat/completions接收OpenAI格式的请求体。之所以用OpenAI兼容格式是方便后续对接各类开源工具链比如一些开源的聊天前端、Agent框架它们天然支持OpenAI协议的API。import asyncio from fastapi import FastAPI, Request from pydantic import BaseModel, Field from transformers import AutoModelForCausalLM, AutoTokenizer import torch app FastAPI() class ChatRequest(BaseModel): prompt: str Field(..., description用户输入) max_tokens: int Field(512, description生成最大token数) temperature: float Field(0.7, description采样温度) # 全局变量保存模型和tokenizer _model None _tokenizer None def load_model(): global _model, _tokenizer model_path /app/model # 镜像内的模型路径 _tokenizer AutoTokenizer.from_pretrained(model_path) _model AutoModelForCausalLM.from_pretrained( model_path, torch_dtypetorch.float16, device_mapauto, low_cpu_mem_usageTrue ) _model.eval() app.on_event(startup) async def startup_event(): # 启动时预加载模型避免第一个请求超时 await asyncio.get_event_loop().run_in_executor(None, load_model) app.post(/v1/chat/completions) async def chat(request: ChatRequest): global _model, _tokenizer if _model is None: load_model() messages [{role: user, content: request.prompt}] inputs _tokenizer.apply_chat_template( messages, add_generation_promptTrue, return_tensorspt ).to(_model.device) outputs _model.generate( inputs, max_new_tokensrequest.max_tokens, temperaturerequest.temperature, do_sampleTrue ) response _tokenizer.decode(outputs[0][inputs.shape[1]:], skip_special_tokensTrue) return {choices: [{message: {role: assistant, content: response}}]}这里有两个细节值得注意。第一模型加载放在startup_event里确保进程启动后先完成模型加载再做服务注册。第二调用app.on_event(startup)时用了run_in_executor把耗时操作放到线程池执行避免阻塞FastAPI的事件循环。虽然模型加载只做一次但阻塞事件循环可能导致健康检查探针无法及时响应。requirements.txt内容如下fastapi0.115.0 uvicorn0.30.1 transformers4.46.0 torch2.4.0 accelerate0.33.0然后写Dockerfile。这里要重点说明——模型权重文件怎么进镜像这是“零配置”的关键步骤。FROM nvidia/cuda:12.1.0-base-ubuntu22.04 WORKDIR /app # 安装 Python 和依赖 RUN apt-get update apt-get install -y python3.11 python3-pip COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # 复制推理代码 COPY app.py . # 复制模型权重到镜像内 COPY model/ /app/model/ # 暴露端口 EXPOSE 8000 CMD [uvicorn, app:app, --host, 0.0.0.0, --port, 8000]模型文件如果超过平台镜像大小上限可以通过平台提供的模型仓库或挂载机制加载这个属于不同平台的差异点。我接触过的主流做法是平台提供一个共享存储的路径你在实例启动时从那个路径把模型复制到本地磁盘——因为共享存储是内网高速访问所以拉取几十GB的文件通常也只要几十秒。3.2 构建镜像并推送到平台仓库在本地项目目录执行docker build -t registry.example.com/qwen3-5-demo:v1 . docker push registry.example.com/qwen3-5-demo:v1推送成功后在函数计算平台的控制台创建一个新的服务。这一步通常需要填写几项信息服务名称随便起方便自己识别就行。镜像地址填写刚才推送的镜像地址。GPU实例规格选择带有GPU的实例类型显存至少大于模型权重大小。环境变量如果有需要配置的参数在这里添加比如MODEL_PATH/app/model。平台一般会提供一个“一键验证”功能它会向你的服务发送一个测试请求。这时候能看到实例启动日志包括模型加载的进度。我第一次测试时从点击“验证”到收到“success”的响应大约花了40秒其中大部分是模型加载时间。这个结果是可以接受的因为实例在完成加载后会常驻后续请求响应会很快。3.3 设置最小实例数和超时时间完成生产级配置部署完成后我做了三件关键配置第一设置最小在线实例数为1。这样服务创建后平台会立刻拉起一个实例并常驻内存消除冷启动对首请求的影响。费用会比纯按需模式高一些但对生产环境来说值得。第二设置超时时间为300秒。这个值的考虑因素是Qwen3.5生成2048个token大约需要30-60秒视具体硬件而定300秒可以确保长对话场景下任务不被中断。第三设置访问鉴权。函数计算平台一般会提供两种方式一种是在API网关层配置密钥需要在请求头中带特定信息另一种是平台生成一个临时的访问凭证。无论哪种都建议开启因为大模型API的调用成本不低如果被外部刷接口账单会很难看。配置完成后可以通过平台生成的HTTP端点测试调用curl -X POST https://your-endpoint.example.com/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer YOUR_TOKEN \ -d {prompt: 你好请介绍一下你自己, max_tokens: 100}返回结果基本和本地推理一致到这里“一键解锁”的核心流程就算完整跑通了。4. 部署完成后的关键优化成本、延迟与稳定性4.1 成本控制如何避免账单爆炸函数计算按实例运行时长计费一个常见误区是以为“没请求就完全免费”但实际上如果设置了最小实例数这些实例会持续产生费用。所以环境区分对待是这个阶段的原则。我的做法是开发环境最小实例数设0完全按需拉起偶尔冷启动慢一点也无所谓生产环境最小实例数设1保证低延迟。另外要密切关注平台的闲置实例回收策略。函数计算平台通常允许你配置实例在闲置多少秒后被回收这个值设短一些比如30秒可以有效降低低峰期的费用。还有一个容易被忽略的省钱点——选择合理的GPU规格。Qwen3.5的量化模型用16GB或24GB显存的实例就能跑没必要选超大显存规格。有些平台按不同GPU型号分别定价选够用的那档就行。4.2 延迟优化从40秒到1秒以内的优化过程冷启动问题解决后另一个需要在意的指标是首Token延迟或单次请求总延迟。我发现影响这个指标最多的因素有四个第一请求体大小。如果你的提示词很长比如几千字模型需要先把全部输入token化并计算出KV Cache这个过程会消耗额外时间。建议对输入长度做限制并提示用户精简提问。第二并发请求数。当多个请求同时打到同一个实例时模型推理是串行的每个请求都会排队。这里可以应用平台的单实例多并发能力——让一个实例同时处理多个请求——但要注意显存带宽限制。我测试下来Qwen3.5在单实例上处理2-4个并发请求吞吐提升明显延迟增加不明显超过这个量延迟会迅速恶化。所以合理设置实例并发度配合平台的自动扩容策略比单纯堆大显存更划算。第三输出长度。生成token数越多耗时越长。在应用层限制max_tokens为合理值比如默认256可以为用户提供长文本场景的独立入口来开大配额这样常规场景的响应速度会更快。第四推理框架的优化选项。transformers库默认的推理方式已经够用但可以通过torch.compile或者vLLM来进一步提升吞吐。我建议在镜像中直接使用支持PagedAttention的推理框架来替代transformers这在并发场景下可以获得数倍的吞吐提升。但这样做需要额外的前期工程适配如果并发需求不高可以先不做保持简单。4.3 稳定性保障日志、监控与告警一个隐藏很深的问题是函数计算平台的实例是不可预测的——它可能在任何时间被回收。如果模型服务在处理请求过程中实例被平台主动回收用户的请求就会失败。常规做法包括在代码里增加断点续跑能力——如果生成过程中断可以基于现有上下文继续生成但这需要接入消息队列之类的组件。用平台提供的日志服务把FastAPI的应用日志、模型加载日志、错误堆栈全部收集起来。平台一般内置这个能力开箱即用。配置可用性告警比如“5分钟内错误率超过10%”时触发通知。我个人比较推荐用平台自带的监控面板搭配日志服务因为配置成本最低。第三方监控系统功能更强大但需要额外部署对于规模不大的项目来说属于“杀鸡用牛刀”。5. 遇到的典型问题与排查实战5.1 模型加载超时实例启动失败的最常见原因我第一次部署时遇到的问题是函数实例一直启动失败日志显示模型加载过程中发生了进程被杀。排查步骤如下第一步查看日志尾部确认是加载到哪个文件时崩溃的。我这里是正在加载权重分片时进程退出。第二步检查实例内存规格。模型加载阶段需要的内存比推理阶段要大不少因为中间缓存和临时张量会在这一阶段集中释放。把实例内存规格从16GB提升到32GB问题解决。第三步如果加内存还不能解决就要考虑在代码里加low_cpu_mem_usageTrue参数并确保device_mapauto已经把模型均匀分配到可用显存上。提示模型加载阶段的内存开销经常是推理时的1.5到2倍选实例规格时千万别卡着下限选。5.2 请求超时或响应极慢不一定是你服务的问题有一次用户反馈响应特别慢我检查了在线实例数和并发配置发现没有异常但响应时间始终在30秒以上。后来发现是函数计算平台的一个冷启动场景虽然配置了最小实例数但那个实例在处理一个很长的请求时新的请求触发了新实例的创建而新实例经历了几十秒的模型加载所以这个新请求就特别慢。解决方式是调整实例的闲置存活时间策略同时提高最小实例数到2或3保证至少有一个实例可以处理新请求其余实例进行模型加载时不会影响到用户。如果你对延迟极度敏感可以使用平台的实例预热功能在服务正式对外开放前主动发送测试请求让实例完成模型加载。5.3 显存溢出发际线危机的制造者还有一种常见崩溃是推理过程中的显存溢出。这通常发生在多个请求并发打到同一实例时。排查方式查看平台监控中的显存使用曲线如果使用率接近100%在请求结束后也没有明显回落说明可能存在显存泄漏或者并发设置过高。处理方式有两种。第一种调低实例并发度从4调到2观察是否还会溢出。第二种在推理请求结束后主动释放无用的中间张量if torch.cuda.is_available(): torch.cuda.empty_cache()另外需要留意模型会为每个请求创建KV Cache长上下文请求的Cache占用非常大。如果业务中可能出现长对话场景并且你是高并发用户群体使用带PagedAttention的推理框架几乎就是唯一的正解——它能有效管理显存碎片化问题比手动调优省心得多。5.4 接口鉴权被绕过“免费”的API被别人刷了最后说一个很现实的问题——接口鉴权。我自己在这个上面踩过一次坑某次我图省事在测试环境没有开启鉴权结果API地址被同行无意间扫到被当作免费接口调了两天账单多出了几十块。虽然金额不大但这个教训很典型。函数计算平台一般提供密钥鉴权要在请求头中带上签名信息或者Bearer Token。如果对外提供服务还建议加上IP白名单或者调用频次限制。大部分平台虽然在网关层提供限流能力但通常需要额外配置别偷懒不做。所有对外暴露的大模型API在未配置任何访问限制之前一律不要对外正式公开。6. 后续扩展从一个API到一个完整服务生态目前你手上已经有一个可用的Qwen3.5推理API了但它还只是一个“裸”模型服务。我从一开始就对这类部署做了一层更实用的包装——把模型API接入到消息应用的机器人或者知识库问答系统里这样才算真正把模型能力用了起来。比如我最近在做的某个内部知识库场景是这么拆的函数计算平台跑Qwen3.5推理服务另一个轻量服务负责检索向量数据库中的相关文档把检索结果拼接到Prompt里再调用这个API生成回答。整个系统的部署复杂度和模型API部署差不多但用户的体感完全不一样——能查到具体业务数据而不是模型在“瞎编”。另外一个值得做的方向是流式输出。当前代码是等模型生成完所有token后一次性返回用户看到的等待时间会比较长。改进方式是使用streamTrue参数把每个生成的token通过SSEServer-Sent Events推送给前端。函数计算平台在API网关层通常支持流式响应透传但需要在代码里做适配。这个改动对用户体验的提升非常明显——首字返回时间从几秒缩短到几百毫秒。我个人的实操体会是函数计算这种部署方式真正的价值并不仅在于“省事”而在于它把部署成本压到了接近零让开发者能更快地把模型能力落地到具体业务里。任何一个对Token消耗有预估、对并发需求大体清楚的项目都值得尝试一下这个路径。
阅读完成 · 觉得有帮助?
咨询建站