1. 从集中训练到广泛推理:算力需求的结构性转折
1.1 一个正在发生的行业拐点
过去两年,大家聊算力,聊的都是训练。千卡集群、万卡集群、H100的交付周期、A100的租赁价格,这些话题占据了绝大部分讨论。但从2024年下半年开始,我明显感觉到一个变化:身边做应用的朋友,问的不再是“怎么训一个模型”,而是“怎么把推理成本压下来”。
这个转折不是偶然的。训练是少数玩家的事,全球真正在训基础大模型的团队可能不超过几十个;但推理是所有人的事,每一个AI应用、每一个智能体、每一个嵌入到业务流里的模型调用,背后都是推理算力在支撑。训练是一次性的重投入,推理是持续性的轻消耗——但架不住量大。
我拿一个具体的数字来说明这个量级差异。一个70B参数的模型,训练一次可能需要几千张卡跑几周;但上线之后,如果日活用户是100万,每人每天调用10次,每次生成500个token,那一天的推理请求就是1000万次。按单张A100跑70B模型(INT8量化)大约每秒能处理2000个token来算,一天需要处理的token总量是50亿,需要的卡数就是……这个账算下来,推理侧的算力需求是训练侧的几十倍甚至上百倍。
这就是为什么“云边端协同”这个概念开始被反复提起。不是因为技术有多新,而是因为需求结构变了——推理不能全部堆在云端。
1.2 为什么推理不能只靠云端
云端推理的问题,我从实际项目中总结了三个:
第一是成本。云端GPU的租赁价格,A100大概在每小时1.5到3美元之间,H100更贵。如果一个应用需要7x24小时在线推理,一个月的成本就是1000到2000美元一张卡。对于中小团队来说,这个数字很难承受。而且推理的负载是波动的,白天高、晚上低,但云端的卡是按时间计费的,低峰期的算力就浪费了。
第二是延迟。云端推理的网络延迟,从用户发起请求到收到第一个token,通常在200毫秒到1秒之间。对于聊天场景,这个延迟可以接受;但对于自动驾驶、工业质检、AR交互这些场景,几百毫秒的延迟就是致命的。端侧推理可以把延迟压到几十毫秒甚至几毫秒。
第三是数据隐私。有些场景的数据不能出本地,比如医疗影像、金融风控、个人语音助手。这些数据必须在端侧或边缘侧处理,不能上传到云端。
但端侧也有端侧的问题:算力有限、内存有限、功耗有限。一个手机端的NPU,算力可能只有几TOPS,跑一个7B模型都费劲,更别说70B了。所以纯粹的端侧推理也不现实。
云边端协同的核心思路就是:把合适的任务放在合适的位置。简单的、延迟敏感的、隐私敏感的推理放在端侧;复杂的、需要大模型的、对延迟不敏感的推理放在云端;介于两者之间的放在边缘侧。端脑科技要构建的,就是这样一套体系。
1.3 端脑科技的定位与切入点
端脑科技这个名字,我最早是在一些边缘计算和推理优化的技术讨论里看到的。他们的切入点很有意思:不做基础大模型,不做云端GPU集群,而是做“云边端协同的算力调度和推理优化”。
具体来说,他们做的事情包括几个层面:
- 端侧:提供轻量级的推理引擎,支持在手机、IoT设备、边缘盒子上跑量化后的小模型(1B到7B),支持INT8、INT4甚至更低精度的量化。
- 边缘侧:提供边缘推理服务器方案,支持在靠近用户的边缘节点部署中等规模的模型(7B到30B),用消费级GPU(比如RTX 3090、4090)或者专用推理芯片来跑。
- 云端:提供云端推理的调度和编排,把复杂的、需要大模型的请求路由到云端,同时做全局的负载均衡和成本优化。
- 协同层:这是最核心的部分,一套统一的调度框架,根据任务类型、延迟要求、数据隐私要求、当前各节点的负载情况,动态决定把推理请求发到哪里。
这个思路和传统的“全部上云”或者“全部端侧”都不一样,它承认了一个现实:没有一种部署方式能解决所有问题,必须混合。
2. 云边端协同算力体系的核心架构拆解
2.1 三层架构的分工与协作逻辑
端脑科技的云边端协同体系,我理解下来是三层结构,但三层之间不是简单的上下级关系,而是有复杂的协作逻辑。
端侧层:这是最靠近用户的一层。端侧设备包括手机、平板、PC、IoT设备、车载终端等。端侧推理的特点是:算力有限但延迟极低,数据不出本地。端脑科技在端侧的策略是“小模型+高量化”。比如一个1.5B的模型,经过INT4量化后,模型大小只有不到1GB,可以在手机的NPU上跑,生成速度大概在每秒10到20个token。这个速度对于很多场景已经够用了,比如输入法联想、本地语音助手、简单的图像分类。
端侧还有一个重要的能力:请求预处理和路由决策。不是所有请求都需要大模型,很多简单请求端侧自己就能处理。端脑科技的端侧引擎会先做一个“难度判断”,如果端侧模型能处理好,就直接在本地出结果;如果判断需要更强的模型,就把请求转发到边缘或云端。这个判断逻辑很关键,它决定了整个体系的效率。
边缘层:边缘层是介于端和云之间的中间层。边缘节点可以是运营商的边缘机房、企业的本地服务器、甚至是一个带GPU的小盒子。边缘层的算力比端侧强得多,可以跑7B到30B的模型,用RTX 3090或者4090这样的消费级GPU就能支撑。边缘层的优势是:延迟比云端低(通常在10到50毫秒),成本比云端低(自己买卡比租云便宜),同时可以处理比端侧复杂得多的任务。
端脑科技在边缘层的策略是“中等模型+中等量化”。比如一个13B的模型,经过INT8量化后,可以在单张RTX 3090上跑,生成速度大概在每秒30到50个token。这个配置可以支撑一个中小企业的内部AI应用,或者一个区域性的服务。
云端层:云端层是算力最强的一层,可以跑70B甚至更大的模型,用A100、H100集群。云端层处理的是最复杂的推理任务,比如长文本生成、复杂推理、多模态理解。云端层的延迟最高,但能力最强。端脑科技在云端层的策略是“大模型+动态批处理”,通过vLLM这样的推理引擎,把多个请求合并成一个批次来处理,提高GPU利用率。
三层之间的协作逻辑,我画一个简单的决策流程:
- 用户发起推理请求。
- 端侧引擎判断请求类型和复杂度。
- 如果端侧能处理,直接本地推理,返回结果。
- 如果端侧处理不了,把请求(或者请求的摘要)发到边缘层。
- 边缘层判断是否能处理,能则本地推理,不能则转发云端。
- 云端处理完成后,结果逐层返回。
这个流程看起来简单,但实现起来有很多细节。比如,端侧怎么判断请求复杂度?边缘层怎么知道自己的负载情况?云端怎么做全局调度?这些都是端脑科技要解决的核心技术问题。
2.2 推理引擎的选型与优化
端脑科技在推理引擎上的选择,我推测是“端侧用自研轻量引擎,边缘和云端用vLLM或类似的高性能引擎”。这个选择是有道理的。
端侧不能用vLLM,因为vLLM依赖PyTorch和CUDA,体积太大,手机和IoT设备跑不起来。端侧需要一个极轻量的推理引擎,可能用C++写,支持ONNX或TFLite格式,能在ARM CPU、NPU、DSP上跑。端脑科技如果自研端侧引擎,核心优化点应该是:内存占用、功耗、启动速度。
边缘和云端用vLLM,是因为vLLM的PagedAttention和连续批处理(Continuous Batching)能大幅提高GPU利用率。我实测过,同样的A100,用vLLM跑Llama 2 70B,吞吐量比用HuggingFace Transformers高3到5倍。这个提升主要来自PagedAttention对KV Cache的管理,以及连续批处理对请求的动态合并。
端脑科技如果在vLLM基础上做优化,我猜他们会做几件事:
- 量化支持:vLLM原生支持FP16和INT8,但INT4的支持还在完善中。端脑科技可能会自己实现INT4的量化推理,进一步降低显存占用。
- 异构调度:vLLM默认假设所有GPU是一样的,但边缘场景下可能有不同型号的GPU混用。端脑科技需要做异构调度,把不同能力的GPU分配到不同的任务上。
- 跨节点协同:vLLM是单节点的,端脑科技需要做跨节点的推理调度,把请求分发到多个边缘节点或云端节点。
2.3 量化策略:INT8、INT4与混合精度
量化是端脑科技体系里的关键技术。没有量化,端侧和边缘侧根本跑不动大模型。
先解释一下量化的基本概念。模型的参数默认是FP32(32位浮点数),后来训练和推理常用FP16(16位)或BF16。量化就是把FP16的参数转换成INT8(8位整数)或INT4(4位整数),从而把模型大小和显存占用降下来。
| 精度 | 位数 | 模型大小(7B) | 显存占用(推理) | 精度损失 |
|---|---|---|---|---|
| FP32 | 32 | 28GB | 28GB+ | 无 |
| FP16 | 16 | 14GB | 14GB+ | 极小 |
| INT8 | 8 | 7GB | 7GB+ | 小 |
| INT4 | 4 | 3.5GB | 3.5GB+ | 中等 |
从表里可以看到,INT8量化后,7B模型只有7GB,一张RTX 3090(24GB)可以轻松跑起来,还能留出空间做KV Cache。INT4量化后,模型只有3.5GB,甚至可以在一些高端手机上跑。
但量化不是没有代价的。INT8量化的精度损失通常很小,在大多数任务上几乎看不出来。INT4量化的精度损失就比较明显了,尤其是在需要精确推理的任务上,比如数学计算、代码生成。端脑科技的做法可能是“混合精度”:模型的大部分层用INT4,但关键的层(比如注意力输出层、FFN的某些层)用INT8或FP16。这样可以在精度和效率之间取得平衡。
我实测过一个13B模型,INT4量化后在RTX 3090上跑,生成速度大概每秒40个token,但做数学题的错误率比FP16高了大概15%。后来把最后几层改成INT8,错误率降到了5%以内,速度只降了10%。这个trade-off是值得的。
2.4 调度层的设计:如何决定请求去哪
调度层是云边端协同的“大脑”。它的核心任务是根据一系列因素,决定一个推理请求应该在哪一层执行。
这些因素包括:
- 延迟要求:如果用户要求响应时间在50毫秒以内,那只能端侧或边缘侧处理;如果允许500毫秒,云端也可以。
- 任务复杂度:简单的分类、匹配任务,端侧小模型就能做;复杂的生成、推理任务,需要云端大模型。
- 数据隐私:如果数据不能出本地,只能在端侧处理。
- 当前负载:如果边缘节点负载满了,请求要转发到云端;如果云端排队太长,可以降级到边缘。
- 成本:端侧成本最低,边缘次之,云端最高。在满足延迟和精度要求的前提下,优先用低成本层。
端脑科技的调度算法,我猜是一个多目标优化问题。它需要在延迟、精度、成本、隐私之间找平衡。实际实现中,可能用一个打分函数:每个层对每个请求打一个分,分数最高的层来处理。打分函数的权重可以根据业务需求调整。
这个调度逻辑听起来简单,但实际做起来很难。因为端侧和边缘侧的负载是动态变化的,网络状况也是动态变化的。端脑科技需要实时收集各层的状态信息,然后快速做出决策。这个决策的延迟必须很低,否则调度本身就成了瓶颈。
3. 实操落地:从零搭建一个云边端协同推理原型
3.1 环境准备与工具选型
如果你也想搭一个云边端协同的推理原型,我把我踩过的坑和用过的工具整理一下。
端侧环境:
- 硬件:一台安卓手机(最好有NPU,比如骁龙8 Gen 2以上),或者一个树莓派5。
- 推理引擎:ONNX Runtime Mobile或者TFLite。如果要用NPU,可以用高通QNN或者华为的CANN。
- 模型:一个1B到3B的小模型,比如Qwen2-1.5B或者Phi-2,量化到INT4。
边缘侧环境:
- 硬件:一台带RTX 3090或4090的服务器。如果没有,用云上的单卡实例也行。
- 推理引擎:vLLM。安装很简单,pip install vllm就行。
- 模型:一个7B到13B的模型,比如Llama 3 8B或者Qwen2-13B,量化到INT8。
云端环境:
- 硬件:A100或H100集群。如果只是测试,用云上的多卡实例。
- 推理引擎:vLLM或者TensorRT-LLM。
- 模型:70B级别的模型,比如Llama 3 70B。
协同层:
- 调度框架:可以用Ray或者Kubernetes做编排,自己写调度逻辑。
- 通信:gRPC或者HTTP/2,端侧和边缘侧之间用MQTT也可以。
- 监控:Prometheus + Grafana,收集各层的延迟、吞吐、负载。
3.2 端侧推理的部署与优化
端侧部署的第一步是模型转换。以ONNX为例,你需要把PyTorch模型导出成ONNX格式,然后量化。
import torch from transformers import AutoModelForCausalLM, AutoTokenizer # 加载模型 model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2-1.5B") tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2-1.5B") # 导出ONNX dummy_input = tokenizer("Hello", return_tensors="pt") torch.onnx.export( model, (dummy_input["input_ids"], dummy_input["attention_mask"]), "qwen2-1.5b.onnx", input_names=["input_ids", "attention_mask"], output_names=["logits"], dynamic_axes={ "input_ids": {0: "batch", 1: "sequence"}, "attention_mask": {0: "batch", 1: "sequence"}, "logits": {0: "batch", 1: "sequence"} }, opset_version=14 )导出之后,用ONNX Runtime的量化工具做INT4量化:
from onnxruntime.quantization import quantize_dynamic, QuantType quantize_dynamic( "qwen2-1.5b.onnx", "qwen2-1.5b-int4.onnx", weight_type=QuantType.QInt4 )量化后的模型大概只有800MB,可以在手机上跑。但要注意,ONNX Runtime Mobile对INT4的支持还不完善,可能需要用自定义算子。
端侧推理的另一个关键是KV Cache管理。端侧内存有限,KV Cache不能无限增长。我的做法是设置一个最大长度,比如2048个token,超过就截断或者滑动窗口。滑动窗口的实现是:当KV Cache满了,丢掉最旧的token的KV,保留最近的。这样可以在有限内存下支持长对话。
3.3 边缘侧vLLM的配置与调优
边缘侧用vLLM,配置相对简单,但有几个参数需要调。
python -m vllm.entrypoints.openai.api_server \ --model Qwen/Qwen2-13B-Instruct \ --quantization int8 \ --max-model-len 4096 \ --gpu-memory-utilization 0.9 \ --max-num-seqs 16 \ --port 8000几个关键参数的解释:
--quantization int8:启用INT8量化。vLLM会自动把模型量化到INT8,显存占用减半。--max-model-len 4096:最大序列长度。这个值越大,KV Cache占用越多。4096对于大多数对话场景够用了。--gpu-memory-utilization 0.9:GPU显存利用率。0.9表示用90%的显存,留10%给系统。--max-num-seqs 16:最大并发序列数。这个值决定了同时能处理多少个请求。太大显存不够,太小吞吐上不去。16是一个比较平衡的值。
我实测下来,RTX 3090跑Qwen2-13B INT8,max-num-seqs=16时,吞吐量大概每秒500个token,延迟在100毫秒左右。如果调到32,吞吐量能到800,但延迟会增加到200毫秒。这个trade-off要根据业务需求来定。
3.4 云端推理的批处理与调度
云端用vLLM,配置和边缘侧类似,但模型更大,需要多卡。
python -m vllm.entrypoints.openai.api_server \ --model meta-llama/Llama-3-70B-Instruct \ --tensor-parallel-size 4 \ --quantization int8 \ --max-model-len 8192 \ --gpu-memory-utilization 0.95 \ --max-num-seqs 64 \ --port 8000--tensor-parallel-size 4表示用4张卡做张量并行。70B模型INT8量化后大概70GB,4张A100(40GB)刚好够。
云端的调度比边缘侧复杂,因为要处理跨节点的请求分发。我的做法是用一个简单的负载均衡器,根据每个节点的当前队列长度来分发请求。队列短的节点优先。
import requests nodes = [ "http://node1:8000", "http://node2:8000", "http://node3:8000" ] def get_least_loaded_node(): min_queue = float('inf') best_node = None for node in nodes: try: resp = requests.get(f"{node}/metrics") queue_len = resp.json()["queue_length"] if queue_len < min_queue: min_queue = queue_len best_node = node except: continue return best_node这个逻辑很简单,但有效。实际生产中可能还需要考虑节点的GPU型号、网络延迟等因素。
3.5 协同层的调度逻辑实现
协同层的调度逻辑,我用一个简单的Python函数来演示:
def route_request(request): # 判断延迟要求 if request.latency_requirement < 50: # 只能端侧或边缘 if request.complexity < 0.3: return "edge" else: return "edge" # 端侧处理不了复杂请求 elif request.latency_requirement < 200: # 边缘或云端 if request.complexity < 0.5: return "edge" else: return "cloud" else: # 都可以,优先低成本 if request.complexity < 0.3: return "edge" elif request.complexity < 0.7: return "edge" else: return "cloud"这个逻辑很粗糙,实际中需要更精细的复杂度评估和负载感知。但核心思想是一样的:根据延迟要求、任务复杂度、当前负载,选择最合适的层。
4. 常见问题与排查技巧实录
4.1 端侧推理的典型问题
问题一:模型转换后精度下降严重。
我遇到过好几次,PyTorch模型导出ONNX后,输出完全不对。排查下来,通常是两个原因:一是算子不支持,ONNX没有对应的算子,导出时被替换成了近似算子;二是动态轴设置不对,导致batch或sequence维度被固定了。
解决办法:先用ONNX Runtime的onnxruntime.tools.check_model检查模型,看有没有不支持的算子。如果有,要么换算子,要么用自定义算子。动态轴的问题,仔细检查dynamic_axes参数,确保所有需要动态的维度都设置了。
问题二:端侧推理速度慢。
手机端跑1.5B模型,如果不用NPU,纯CPU跑,速度可能只有每秒2到3个token,根本没法用。解决办法:一定要用NPU。高通的QNN、华为的CANN、苹果的Core ML,都能把推理速度提升5到10倍。如果设备没有NPU,那就只能降模型大小,用0.5B的模型。
问题三:KV Cache内存溢出。
端侧内存有限,长对话时KV Cache会爆。解决办法:设置最大长度,超过就滑动窗口。或者用PagedAttention的思想,把KV Cache分页管理,但端侧实现比较复杂。
4.2 边缘侧vLLM的常见坑
坑一:显存不够,模型加载失败。
vLLM加载模型时,会先分配显存。如果gpu-memory-utilization设得太高,比如0.95,而系统还有其他进程占用显存,就会OOM。解决办法:设成0.85到0.9,留一些余量。或者用--swap-space参数,把一部分KV Cache放到CPU内存。
坑二:吞吐量上不去。
vLLM的吞吐量取决于max-num-seqs和max-model-len。如果这两个值设得太小,GPU利用率上不去。解决办法:根据显存大小,尽量调大这两个值。RTX 3090跑13B INT8,max-num-seqs可以设到32,max-model-len设到4096。
坑三:请求排队太长。
如果并发请求太多,vLLM会排队。排队时间太长,用户体验就差。解决办法:加节点,做负载均衡。或者用优先级队列,重要请求优先处理。
4.3 协同调度的常见问题
问题一:调度决策延迟高。
如果调度层每次都要查询所有节点的状态,决策延迟可能达到几十毫秒。解决办法:缓存节点状态,每隔几秒更新一次。或者用近似的负载信息,不要求完全准确。
问题二:跨层通信失败。
端侧到边缘侧的网络可能不稳定,请求丢失或超时。解决办法:加重试机制,设置合理的超时时间。如果边缘侧不可用,降级到云端。
问题三:数据一致性。
端侧和边缘侧的模型版本可能不一致,导致同样的请求在不同层得到不同结果。解决办法:统一模型版本管理,每次更新模型时,所有层同步更新。或者用版本号标记请求,确保同一请求在同一版本上处理。
4.4 常见问题速查表
| 问题 | 可能原因 | 排查方法 | 解决办法 |
|---|---|---|---|
| 端侧模型精度下降 | 算子不支持或动态轴错误 | 用ONNX检查工具 | 换算子或修正动态轴 |
| 端侧推理慢 | 没用NPU | 检查是否调用了NPU | 启用NPU加速 |
| KV Cache溢出 | 序列太长 | 监控内存占用 | 滑动窗口或分页管理 |
| vLLM OOM | 显存利用率太高 | 查看GPU显存 | 降低gpu-memory-utilization |
| 吞吐量低 | max-num-seqs太小 | 查看GPU利用率 | 调大max-num-seqs |
| 调度延迟高 | 状态查询太频繁 | 测量调度耗时 | 缓存节点状态 |
| 跨层通信失败 | 网络不稳定 | 查看网络日志 | 加重试和降级 |
| 模型版本不一致 | 更新不同步 | 检查各层模型版本 | 统一版本管理 |
5. 这套体系适合谁,以及我的一些实操心得
5.1 适合的场景与团队
云边端协同的算力体系,不是所有团队都需要。我总结下来,适合这几类:
第一类:有延迟敏感场景的团队。比如做自动驾驶、工业质检、AR/VR的团队,端侧和边缘侧推理是刚需。云端推理的几百毫秒延迟,在这些场景下不可接受。
第二类:有数据隐私要求的团队。比如做医疗、金融、政务的团队,数据不能出本地。端侧推理是唯一选择。
第三类:成本敏感的团队。如果全部用云端推理,成本太高。把一部分推理放到边缘侧,用自购的GPU,长期来看能省不少钱。我算过一笔账:一个中等规模的AI应用,如果全部用云端A100,一年成本大概50万;如果用边缘侧RTX 4090加云端混合,一年成本可以降到20万左右。
第四类:做AI Agent和多AI协作的团队。Agent的推理请求很分散,有的简单有的复杂。云边端协同可以根据请求类型动态调度,提高整体效率。
5.2 我踩过的坑和总结的经验
经验一:不要追求一步到位。我一开始就想搭一个完整的云边端协同体系,结果发现太复杂了,光是调度逻辑就写了上千行,bug一堆。后来我改成先做端侧,再做边缘侧,最后做协同。每一步都跑通了,再往上加。这样稳得多。
经验二:量化不是万能的。INT4量化确实能把模型压得很小,但精度损失在某些任务上很致命。我的做法是:先试INT8,如果显存够就用INT8;如果不够,再试INT4,但一定要做精度评估。评估的方法很简单:拿100条测试数据,对比量化前后的输出,看差异有多大。如果差异超过10%,就要考虑混合精度。
经验三:调度逻辑要简单可靠。我见过一些团队,调度逻辑写得非常复杂,考虑了十几个因素,结果经常出bug。我的建议是:先做最简单的调度,比如只根据延迟要求来路由。跑通了,再慢慢加因素。每加一个因素,都要做充分的测试。
经验四:监控比优化更重要。云边端协同体系,各层的状态是动态变化的。如果没有监控,你根本不知道问题出在哪。我的做法是:每一层都部署Prometheus,收集延迟、吞吐、错误率、显存占用等指标。然后用Grafana做统一展示。这样出问题时,一眼就能看出是哪一层的问题。
经验五:端侧模型要定期更新。端侧模型一旦部署,更新很麻烦。但如果不更新,端侧的能力会越来越落后。我的做法是:端侧模型每季度更新一次,用OTA的方式推送。更新时要注意兼容性,新模型要能处理旧模型的请求格式。
5.3 后续可以扩展的方向
这套体系搭起来之后,还可以往几个方向扩展:
方向一:联邦学习。端侧设备可以在本地训练小模型,然后把梯度上传到云端聚合。这样既能利用端侧数据,又能保护隐私。
方向二:动态模型切换。根据当前负载和任务类型,动态切换端侧和边缘侧的模型。比如低峰期用大模型,高峰期用小模型。
方向三:多模态推理。现在主要是文本推理,后续可以扩展到图像、语音、视频。端侧做预处理,边缘侧做特征提取,云端做多模态融合。
方向四:自动扩缩容。根据请求量的变化,自动增加或减少边缘节点。这需要和Kubernetes集成,用HPA(Horizontal Pod Autoscaler)来做。
我个人在实际操作中的体会是,云边端协同不是一个纯技术问题,更多的是一个工程问题。技术方案有很多,但能不能落地,取决于你对业务场景的理解,对成本、延迟、精度的权衡,以及团队的工程能力。端脑科技的这个方向是对的,但具体能做到什么程度,还要看他们的工程实现和生态建设。