【LLM推理与Serving⑧】多机多卡Serving:TP/PP/负载均衡与弹性扩缩容全攻略

【LLM推理与Serving⑧】多机多卡Serving:TP/PP/负载均衡与弹性扩缩容全攻略

系列文章索引:本系列从基础概念到工程实践,系统梳理LLM推理与Serving的核心知识。本文为第8篇,深入讲解多机多卡场景下的并行策略、负载均衡与弹性架构。

一、开篇:单卡不够用时怎么办?多机多卡的并行维度

做LLM Serving的同学,迟早会遇到一个问题:单张GPU放不下模型了,或者单卡吞吐不够了,怎么办?

答案很简单:加卡。但"加卡"这两个字背后,有一整套的并行策略和工程架构需要搞清楚。

你可能听过这些名词:DP、TP、PP、EP、ZeRO......它们分别是什么意思?什么时候用TP,什么时候用PP?多机之间怎么通信?流量大了怎么做负载均衡?流量忽高忽低怎么做弹性扩缩容?

这篇文章就带你把这些问题一个个讲清楚。我们从最基础的四种并行方式讲起,然后深入到Serving场景下的TP/PP选型,再到负载均衡策略和弹性扩缩容架构,最后聊聊生产环境中vLLM等框架的二次开发实践。

先建立一个直觉:多机多卡Serving的本质,是用更多的硬件资源,换取更大的模型容量、更高的吞吐、或更低的延迟------同时付出通信开销、工程复杂度和成本的代价。

二、四种并行方式对比:DP/TP/PP/EP

在深入Serving之前,我们先把四种经典并行方式的概念过一遍。虽然这些概念更多来自训练侧,但推理侧同样适用,而且理解起来更简单(因为没有反向传播)。

2.1 数据并行(Data Parallel, DP)

切分对象:数据。每张卡上放完整的模型,不同的卡处理不同的输入数据。

复制代码
GPU0: [完整模型] + [数据分片0]
GPU1: [完整模型] + [数据分片1]
GPU2: [完整模型] + [数据分片2]
GPU3: [完整模型] + [数据分片3]

优点 :实现简单,线性扩展(理想情况下N卡=N倍吞吐)。

缺点 :每张卡都要存完整模型,模型太大时单卡放不下。

适用场景:模型单卡能放下,但吞吐不够,需要横向扩容。

2.2 张量并行(Tensor Parallel, TP)

切分对象:模型参数(按层内的张量维度切分)。

以一个线性层 Y = XA 为例,我们可以把权重矩阵A按列切分:

复制代码
A = [A1 | A2]    (按列切分)
Y = X[A1 | A2] = [XA1 | XA2] = [Y1 | Y2]

每张卡只存一部分权重,计算时各自算一部分,最后通过All-Gather拼接结果。

复制代码
GPU0: [Layer1的前半部分] → [Layer2的前半部分] → ...
GPU1: [Layer1的后半部分] → [Layer2的后半部分] → ...
        ↑ 每层之间需要All-Reduce通信

优点 :模型被切分到多张卡上,可以放更大的模型;延迟较低(层内并行)。

缺点 :通信量大(每层都要通信),对网络带宽敏感;通常只能在单机内做(NVLink)。

适用场景:模型单层太大、单卡放不下,或者追求低延迟。

2.3 流水线并行(Pipeline Parallel, PP)

切分对象:模型层(按层的维度切分)。

把模型的不同层放到不同的卡上,数据从第一张卡流进去,经过每一层计算,最后从最后一张卡输出。

复制代码
GPU0: Layer 0~7  →  传递激活值  →  GPU1: Layer 8~15  →  传递激活值  →  GPU2: Layer 16~23  →  ...

优点 :通信量小(只在层边界传递激活值);可以跨机器做。

缺点 :有Pipeline Bubble(流水线气泡)------前面的卡算完后面的卡还没开始,硬件利用率低;延迟高(数据要流经所有卡)。

适用场景:模型层数很多,跨机器部署大模型。

2.4 专家并行(Expert Parallel, EP)

切分对象:MoE模型中的Expert。

对于混合专家模型(MoE),每个token只激活部分专家,我们可以把不同的专家放到不同的卡上。

复制代码
GPU0: Expert 0, Expert 1, ...
GPU1: Expert 2, Expert 3, ...
GPU2: Expert 4, Expert 5, ...

优点 :对于MoE模型,扩展效率很高。

缺点 :只适用于MoE架构;路由策略复杂。

适用场景:MoE大模型推理。

2.5 四种并行方式对比表

并行方式 切分对象 通信量 适用模型大小 延迟影响 复杂度
DP(数据并行) 数据 小(推理时几乎没有) 单卡能放下 无影响 低
TP(张量并行) 层内张量 大(每层都要) 单层太大 降低延迟 中
PP(流水线并行) 模型层 中(层间传递) 层数很多 增加延迟 中高
EP(专家并行) MoE专家 中 MoE大模型 视情况 高

一句话记住:

  • 吞吐不够 → 加DP
  • 模型太大单层放不下 → 用TP
  • 模型太大层数太多 → 用PP
  • MoE模型 → 加EP

三、Tensor Parallel Serving:TP切分什么、收益与代价

下面我们重点看推理Serving场景下的TP和PP,这是最常用的两种模型并行方式。

3.1 TP在推理时到底切分了什么

以LLaMA的一个Transformer层为例,TP主要切分这些地方:

  1. Attention的QKV投影:按输出维度切分,每张卡算一部分head
  2. Attention的输出投影:按输入维度切分,最后All-Reduce
  3. MLP的Gate/Up投影:按输出维度切分
  4. MLP的Down投影:按输入维度切分,最后All-Reduce

简单说:凡是矩阵乘法,能按行或列切分的地方都切了。

python 复制代码
# 伪代码:TP下的Attention计算
def attention_tp(x, num_heads, head_dim, tp_size):
    """
    张量并行下的Attention:
    - QKV按head维度切分到不同GPU
    - 每张卡独立计算自己的attention
    - 输出投影后做All-Reduce
    """
    # 每张卡只持有部分head的QKV权重
    local_num_heads = num_heads // tp_size
    
    # 1. 线性投影得到Q, K, V(每张卡只算自己的部分)
    q = linear(x, W_q_local)  # [batch, seq_len, local_num_heads * head_dim]
    k = linear(x, W_k_local)
    v = linear(x, W_v_local)
    
    # 2. 本地计算Attention(不需要通信)
    attn_output = scaled_dot_product_attention(q, k, v)
    
    # 3. 输出投影
    out = linear(attn_output, W_o_local)
    
    # 4. All-Reduce 汇总所有卡的结果
    out = all_reduce(out)
    
    return out

3.2 TP的收益与代价

收益:

  • 降低延迟:因为每层的计算被分到多张卡上并行执行,单token生成时间可以缩短
  • 放更大的模型:单卡放不下的模型,TP可以把参数分散到多张卡

代价:

  • 通信开销:每层都需要All-Reduce通信。对于A100这种有NVLink的机器,通信很快;但如果是PCIe连接的消费级显卡,通信可能成为瓶颈
  • 显存利用率:虽然参数被分摊了,但KV Cache还是每张卡都要存完整的(因为每张卡都需要完整的KV来做attention)------等等,不对,TP下KV Cache也是分片的。让我纠正一下:TP下每张卡只存部分head的KV,所以KV Cache也是分摊的
  • 编程复杂度:需要引入通信库(NCCL),初始化分布式环境

3.3 TP的适用场景

  • 低延迟场景:比如实时对话,对TTFT和TPOT都有要求,TP能并行计算减少延迟
  • 大模型单卡放不下:比如70B模型在A100-80G上FP16需要140GB显存,单卡肯定放不下,用TP=2就可以放下
  • 单机多卡:TP最适合单机内的多卡,因为NVLink的带宽远高于PCIe和网络

经验值:TP通常做到2或4比较常见。TP=8虽然理论上更快,但通信开销和调度开销可能抵消收益。

四、Pipeline Parallel Serving:PP切分什么、Bubble问题

4.1 PP在推理时怎么工作

PP把模型的层按顺序分配到不同的GPU上。比如一个32层的模型,PP=2的话:

  • GPU0:Layer 0~15
  • GPU1:Layer 16~31

推理时,输入先到GPU0,算完前16层,把激活值传给GPU1,GPU1接着算后16层,最后输出。

复制代码
时间 →
GPU0: [计算Layer0-15] [空闲]         [计算下一个batch的Layer0-15]
GPU1: [等待]          [计算Layer16-31] [等待]                   ...
       ↑ 这就是Pipeline Bubble(气泡)

4.2 Pipeline Bubble问题

PP最大的问题就是流水线气泡(Pipeline Bubble)------因为数据是顺序流过各阶段的,在填充和排空阶段,总有GPU是空闲的。

举个例子:PP=4,batch_size=1时,GPU利用率只有25%(因为同一时间只有一张卡在算,其他三张在等)。

怎么减少气泡?增大batch size / micro-batch数量。

复制代码
PP=4, 4个micro-batch的情况:

GPU0: [m0] [m1] [m2] [m3]
GPU1:      [m0] [m1] [m2] [m3]
GPU2:           [m0] [m1] [m2] [m3]
GPU3:                [m0] [m1] [m2] [m3]
       ↑ 填充阶段 ↑  满载阶段  ↑ 排空阶段

可以看到,当micro-batch数量远大于PP阶段数时,气泡的比例就很小了。公式如下:

复制代码
气泡比例 = (PP_size - 1) / (PP_size + num_microbatches - 1)

当num_microbatches很大时,气泡比例趋近于 (PP_size - 1) / num_microbatches,几乎可以忽略。

但在推理Serving场景中,情况不一样:

  • 推理是自回归生成的,每一步都要等前一个token生成完才能生成下一个
  • 所以PP推理的bubble问题比训练更严重------因为每个token的生成都要经历一次流水线的填充和排空

4.3 PP的适用场景

  • 超大模型:比如千亿参数模型,即使TP也放不下,需要PP+TP组合
  • 跨机器部署:PP的通信量相对TP小很多(只在层边界传激活值),更适合跨网络的多机场景
  • 吞吐优先而非延迟优先:PP会增加延迟(数据要流经所有卡),但通过大batch可以获得不错的吞吐

4.4 TP+PP组合

实际生产中,大模型通常是TP+PP组合使用的:

  • 单机内用TP(利用NVLink高带宽)
  • 跨机器用PP(减少跨机通信量)

比如一个70B模型,部署在2台8卡A100上:

  • 每台机器内 TP=8(8张卡做张量并行)
  • 两台机器之间 PP=2(流水线并行)
  • 总并行度:TP8 × PP2 = 16卡

五、TP/PP估算与部署建议

说了这么多理论,来点实用的:怎么估算我的模型需要几张卡?该用TP还是PP?

5.1 显存估算公式

先回忆一下LLM推理的显存占用:

复制代码
总显存 = 模型参数显存 + KV Cache显存 + 激活值显存 + 运行时开销

模型参数显存(FP16/BF16):

复制代码
参数量 × 2 bytes
例如:7B → 14GB,70B → 140GB,405B → 810GB

KV Cache显存(FP16/BF16):

复制代码
2 × num_layers × num_heads × head_dim × seq_len × batch_size × 2 bytes
(前面的2是K和V各一份)

简化一下:对于LLaMA架构,KV Cache大约是 参数量 × seq_len / hidden_dim × batch_size × 2 bytes

经验值:

  • 7B模型,4096上下文,batch_size=32,KV Cache大约 4~6GB
  • 70B模型,4096上下文,batch_size=32,KV Cache大约 40~60GB

5.2 典型配置参考

以下是一些常见模型在A100-80G上的部署配置参考(FP16,留出余量给KV Cache):

模型大小 TP=1 TP=2 TP=4 TP=8
7B 单卡轻松 - - -
13B 勉强(KV空间小) 轻松 - -
34B 放不下 勉强 轻松 -
70B 放不下 放不下 勉强 轻松
405B 放不下 放不下 放不下 需PP+TP

5.3 部署优先级顺序

一个实用的部署策略优先级:

复制代码
单卡能放下 → 直接上(最简单,成本最低)
    ↓ 单卡放不下
用TP(优先单机内TP,延迟低,实现简单)
    ↓ 单机卡不够
用PP+TP组合(跨机器,PP负责跨机,TP负责机内)
    ↓ 吞吐不够
加DP(数据并行,多副本,线性扩展吞吐)

为什么DP放在最后? 因为DP是"堆机器换吞吐",成本最高。先把单副本的性能榨干(TP/PP/量化/优化),再考虑横向扩展。

5.4 vLLM中启用TP的示例

bash 复制代码
# vLLM 启用 Tensor Parallel (TP=2)
vllm serve meta-llama/Llama-2-70b-chat-hf \
  --tensor-parallel-size 2 \
  --gpu-memory-utilization 0.9 \
  --max-model-len 4096

# 启用 Pipeline Parallel (PP=2) + TP=4
# vllm serve meta-llama/Llama-2-405b-chat-hf \
#   --tensor-parallel-size 4 \
#   --pipeline-parallel-size 2 \
#   --gpu-memory-utilization 0.9

就这么简单,vLLM已经帮你封装好了分布式通信的细节。

六、负载均衡:不能只看QPS

当你有多个推理实例(DP副本)时,怎么把请求分配到各个实例上?这就是负载均衡要解决的问题。

6.1 为什么LLM Serving的负载均衡不一样

普通的Web服务,负载均衡策略很简单:轮询(Round Robin)、随机、最少连接数......基本够用。

但LLM Serving不一样,因为请求的"重量"差异极大:

  • 有的请求输入只有10个token,输出50个token
  • 有的请求输入有4000个token,输出2000个token
  • Prefill阶段(处理输入)是计算密集型的
  • Decode阶段(生成输出)是访存密集型的

不同的请求对GPU的压力完全不同。如果简单用轮询,可能出现有的GPU忙死、有的GPU闲死的情况。

6.2 常用负载均衡策略对比

策略 原理 优点 缺点
Round Robin 按顺序轮流分配 实现简单 完全不考虑负载,容易不均匀
最少连接数 分给当前连接最少的实例 比RR好 连接数不等于实际负载
最少正在处理token数 分给当前正在处理token最少的实例 更精准 需要统计token数,有开销
基于队列长度 看每个实例的请求队列长度 反映真实排队压力 需要框架支持队列长度查询
基于GPU利用率 分给GPU利用率最低的实例 直接反映硬件压力 GPU利用率有滞后,不准
Prefix-aware路由 相同前缀的请求路由到同一实例(利用Prefix Cache) 提升缓存命中率 实现复杂,需要解析请求

6.3 推荐策略:基于队列长度 + Prefix感知

对于LLM Serving,比较推荐的组合策略是:

  1. 主策略:基于请求队列长度 / 正在处理的token数

    • 这是最能反映实例"忙不忙"的指标
    • 很多推理框架(vLLM、TGI)都暴露了相关的metrics
  2. 辅助策略:Prefix感知路由

    • 对于有大量共享前缀的场景(比如SaaS产品,系统提示词相同),把相同前缀的请求路由到同一个实例,可以大幅提升Prefix Cache命中率
    • 实现方式:对prompt做hash,相同hash的请求路由到同一实例(类似一致性哈希)
python 复制代码
# 伪代码:Prefix感知的负载均衡
class PrefixAwareLoadBalancer:
    def __init__(self, instances, prefix_length=100):
        self.instances = instances
        self.prefix_length = prefix_length  # 取前N个字符做hash
    
    def select_instance(self, prompt):
        # 1. 提取前缀
        prefix = prompt[:self.prefix_length]
        prefix_hash = hash(prefix)
        
        # 2. 计算候选实例(一致性哈希)
        candidate_idx = prefix_hash % len(self.instances)
        candidate = self.instances[candidate_idx]
        
        # 3. 检查候选实例负载是否过高,如果过高则选次优
        if candidate.queue_size() < self.max_queue:
            return candidate
        else:
            # 降级:选队列最短的
            return min(self.instances, key=lambda x: x.queue_size())

6.4 健康检查与背压

健康检查:

  • 不仅要检查进程是否存活,还要检查GPU是否正常、模型是否加载成功
  • 建议做"深度健康检查":发一个测试请求,看能不能正常返回
  • 不健康的实例要及时从负载均衡中摘掉

背压(Backpressure):

  • 当所有实例都满载时,不能把请求直接拒掉(也不能无限排队)
  • 应该有一个排队队列,超出队列长度返回503(服务不可用)或排队中
  • 客户端需要有重试和降级逻辑
python 复制代码
# 伪代码:带背压的请求处理
async def handle_request(request):
    if current_queue_size >= max_queue_size:
        # 返回503,告诉客户端稍后重试
        return Response(status_code=503, content="服务繁忙,请稍后重试")
    
    # 加入队列
    queue_item = QueueItem(request)
    await queue.put(queue_item)
    
    # 等待处理结果
    result = await queue_item.result_future
    return result

七、弹性扩缩容:不止看GPU利用率

线上流量是波动的------白天高峰、深夜低谷。如果一直按峰值配机器,成本太高;如果按低谷配,高峰时又扛不住。

弹性扩缩容(Auto Scaling)就是解决这个问题的:流量大了自动加机器,流量小了自动减机器。

7.1 扩容指标:不止GPU利用率

普通Web服务扩容看CPU利用率,但LLM Serving不能只看GPU利用率。为什么?

因为GPU利用率高不一定是真的"忙"------可能只是在等KV Cache,或者batch size太小导致GPU没吃饱。

更合理的扩容指标组合:

指标 说明 扩容阈值参考
GPU利用率 最直观,但有滞后 持续 > 80%
请求队列长度 最灵敏,反映排队压力 队列 > 阈值持续N秒
P99延迟 反映用户体验 P99 > SLA阈值
拒绝请求数 最直接的压力信号 出现503错误
正在处理的token数 反映实际负载 接近上限

推荐做法 :用多个指标组合判断,比如"GPU利用率>80% 且 队列长度>10 且 持续30秒"才扩容。单一指标容易误判。

7.2 扩缩容策略

Scale Out(扩容)
  • 触发条件:负载持续超过阈值
  • 扩容步长:一次加几台?建议从小步开始,观察效果再调整。比如一次加2台,而不是一下加10台
  • 预热(Pre-warm):新实例启动时需要加载模型,这个过程可能要几分钟。不能等满了才扩容,要提前预判
Scale In(缩容)
  • 触发条件:负载持续低于阈值
  • 缩容步长:比扩容更保守,一次减1-2台
  • 冷却时间(Cooldown):缩容后要等一段时间再判断是否继续缩,避免频繁抖动
冷却时间(Cooldown)
  • 扩容后冷却N分钟再判断是否继续扩
  • 缩容后冷却M分钟再判断是否继续缩(M通常比N大,缩容要更保守)
  • 目的:防止指标波动导致频繁扩缩容
python 复制代码
# 伪代码:弹性扩缩容控制器
class AutoScaler:
    def __init__(self, min_replicas, max_replicas):
        self.min_replicas = min_replicas
        self.max_replicas = max_replicas
        self.current_replicas = min_replicas
        self.last_scale_time = 0
        self.cooldown_seconds = 300  # 5分钟冷却
    
    def check_and_scale(self, metrics):
        # 冷却期内不操作
        if time.time() - self.last_scale_time < self.cooldown_seconds:
            return
        
        need_scale_out = (
            metrics['gpu_util'] > 0.8 and 
            metrics['queue_size'] > 10 and
            metrics['p99_latency'] > 2.0  # 秒
        )
        
        need_scale_in = (
            metrics['gpu_util'] < 0.3 and
            metrics['queue_size'] == 0 and
            self.current_replicas > self.min_replicas
        )
        
        if need_scale_out and self.current_replicas < self.max_replicas:
            self.scale_out(step=2)
            self.last_scale_time = time.time()
        elif need_scale_in:
            self.scale_in(step=1)
            self.last_scale_time = time.time()

7.3 预热与快速启动

扩容最大的痛点是新实例启动慢------加载一个70B模型可能要好几分钟。等你启动完,高峰可能已经过去了。

怎么解决?

  1. 预热池(Warm Pool):保持几台预热好的实例待命,需要时立即挂上流量
  2. 预测式扩容:基于历史流量模式预测,提前扩容。比如每天早上9点流量上升,8:45就开始扩容
  3. 模型分片加载:从分布式存储/本地缓存快速加载模型权重
  4. 镜像优化:把模型权重打包到Docker镜像里?不推荐,镜像太大。更好的方式是用PVC或节点本地缓存
  5. Serverless方案:云厂商的Serverless推理服务(如AWS SageMaker Endpoints、阿里云PAI-EAS)底层已经帮你做了弹性

八、云端vLLM框架二次开发:分层原则与工程实践

很多团队会基于vLLM做二次开发,加上自己的业务逻辑。这里分享一些架构设计上的经验。

8.1 分层原则

一个好的二次开发架构,应该遵循分层原则:

复制代码
┌─────────────────────────────────┐
│  业务层(Business Layer)        │  ← 业务逻辑、鉴权、计费、限流
├─────────────────────────────────┤
│  编排层(Orchestration Layer)   │  ← 负载均衡、弹性扩缩容、服务发现
├─────────────────────────────────┤
│  引擎层(Engine Layer)          │  ← vLLM / TensorRT-LLM 引擎
└─────────────────────────────────┘

核心原则 :尽量不要改引擎层的代码,而是在外面包一层。

为什么?因为vLLM迭代很快,如果你改了它的源码,后续升级会非常痛苦------每次升级都要解决冲突。

8.2 常见需求的推荐位置

需求 推荐位置 实现方式
用户鉴权 / API Key 业务层 在API网关或业务服务中做
限流 / 配额 业务层 Redis计数、令牌桶
计费 业务层 统计token用量,对接计费系统
负载均衡 编排层 独立的LB服务,或用K8s Service + Istio
弹性扩缩容 编排层 K8s HPA / KEDA / 自研控制器
请求队列管理 编排层 独立的队列服务,异步派发
Prefix Cache优化 引擎层(尽量不动) 通过路由策略间接优化
自定义算子 引擎层 以插件形式接入,而非直接改源码
监控日志 各层都有 统一接入Prometheus + Grafana

8.3 参考架构

一个典型的生产级LLM Serving架构:

复制代码
                    ┌──────────┐
                    │  API网关  │ ← 鉴权、限流、路由
                    └────┬─────┘
                         │
                    ┌────▼─────┐
                    │ 业务服务  │ ← 业务逻辑、计费、审计
                    └────┬─────┘
                         │
              ┌──────────▼──────────┐
              │   负载均衡/调度器     │ ← 智能路由、队列管理
              └──┬───┬───┬───┬─────┘
                 │   │   │   │
           ┌─────▼┐ ┌▼──┐ ┌▼──┐ ┌▼─────┐
           │vLLM-1│ │v-2│ │v-3│ │vLLM-N│  ← DP副本
           └──────┘ └───┘ └───┘ └──────┘
              A100   A100  A100   A100

8.4 工程坑位提醒

最后分享一些踩过的坑:

  1. 版本升级要谨慎:vLLM每个版本的性能和行为可能有差异,升级前一定要做完整的回归测试。不要追新,稳定最重要。

  2. 显存碎片问题:长时间运行后,PagedAttention的显存可能产生碎片,导致可用显存越来越少。解决方案:定期重启实例,或者监控可用显存自动重启。

  3. 请求超时处理:一定要设置超时时间,否则一个超长请求可能占着茅坑不拉屎,把整个实例拖垮。超时后要确保资源正确释放。

  4. 优雅关闭:缩容下线实例时,要等正在处理的请求完成再关闭,不能强杀。K8s里可以用preStop钩子。

  5. 日志要结构化:不要用print打日志,用JSON格式的结构化日志,方便后续检索和分析。

  6. 监控要全链路:从API网关到引擎层,每个环节的延迟和错误率都要监控。出问题时能快速定位是哪一层的锅。

九、小结与思考

多机多卡Serving是LLM从Demo走向生产的必经之路。我们来回顾一下本文的核心内容:

  1. 四种并行方式:DP扩吞吐、TP降延迟+放更大模型、PP放超大模型、EP专用于MoE
  2. TP vs PP:TP适合单机内、低延迟场景;PP适合跨机器、大模型场景。生产中常用TP+PP组合
  3. 部署优先级:单卡→TP→PP→DP,先榨干单副本性能再横向扩展
  4. 负载均衡:不能只看QPS,要看队列长度、正在处理的token数。Prefix感知路由能提升缓存命中率
  5. 弹性扩缩容:不能只看GPU利用率,要多指标组合。缩容比扩容更保守,预热池和预测式扩容能解决启动慢的问题
  6. 二次开发:遵循分层原则,尽量不要改引擎层源码,在外面包业务层和编排层

最后想说:架构是演化出来的,不是设计出来的。 一开始不用搞太复杂,从单实例开始,流量上来了再加负载均衡,再上来了再加弹性扩缩容。每一步都要有数据支撑,而不是"感觉需要"。

相关推荐
飞哥数智坊25 分钟前
DSH+DeepSeek 实测 Anatomy Skill:让技术原理可视化
人工智能
西安小哥26 分钟前
AI 网关的语义缓存层:精确缓存吃掉 21% 调用量之后我才做向量
aigc
长不大的杨瑞杰31 分钟前
ChatGPT 广告技术栈架构拆解:多轮意图、LLM 工具编排、ANN 召回与拍卖闭环
人工智能·chatgpt·系统架构·推荐系统·广告
迪菲赫尔曼1 小时前
【基础篇 26】第一次在服务器完成训练:准备数据、断线继续、检查成果与备份
运维·服务器·人工智能·机器学习·计算机视觉
小年糕是糕手1 小时前
【AI】用 AI 做自己的个人网站(上):选模板、写提示词,做出第一版
人工智能·app·网页开发·codex·index·styles·0基础教程
硅谷秋水1 小时前
RoboAtom:机器人学习的大规模原子-动作监督
人工智能·机器学习·计算机视觉·机器人
vipxieliang1 小时前
具身智能2026:从实验室演示到万台级量产
人工智能
lucas_AI1 小时前
花旗银行教你算 AI 的账:省下的时间要和审查成本、残余风险记在同一本账上
人工智能