私有 LLM 多机多卡分布式推理:Pipeline Parallel vs Tensor Parallel 踩坑全记录

适用版本 :vLLM 0.18.0、Ray 2.40+、PyTorch 2.10、Python 3.12
实战模型 :Qwen3.5-72B(双节点 A100 80G × 8)/ DeepSeek-V3(四节点 H100 × 8)
网络互联:InfiniBand HDR 200Gb/s(节点间)/ NVLink(节点内)


前言

单卡跑通了,多卡也跑通了,但当模型大到单节点放不下,你就要踏入多机多卡的领地。

这一步的跨度比从单卡到多卡大得多。节点间通信、NCCL 网络配置、Ray 集群管理、环境一致性......任何一个环节出问题,表现都是同一个症状:卡住不动,没有报错,等一会儿 timeout

本文记录从双节点跑 Qwen3.5-72B 到四节点跑 DeepSeek-V3 的完整踩坑路径,10 个坑,每个坑都给出可直接用的诊断命令和修复方案。


一、先搞清楚两种并行的本质区别

在动手之前,必须先把 Tensor Parallel(TP)和 Pipeline Parallel(PP)的本质区别理解透------选错并行策略是最大的性能浪费,比踩任何技术坑都代价高。

Tensor Parallel(张量并行)

把单层的权重矩阵横向切片,分布到多块 GPU 上,每张卡计算一部分,再通过 AllReduce 合并结果。

python 复制代码
一个 Attention 层的 W_q 矩阵(维度 d × d):
GPU 0: W_q 的前 d/4 列
GPU 1: W_q 的第 2 个 d/4 列
GPU 2: W_q 的第 3 个 d/4 列
GPU 3: W_q 的后 d/4 列
→ 每个 Token 的每一层,四张卡都要参与计算并同步

核心特征:每个 Token 都需要所有 GPU 协同计算,通信发生在每一层。通信延迟直接影响 TTFT,对网络带宽要求极高(需要 NVLink 或 InfiniBand)。

Pipeline Parallel(流水线并行)

把模型的切分给不同 GPU(或节点),每个 GPU 只负责若干层,前一段的输出(激活值)传给下一段。

python 复制代码
Qwen3.5-72B(80 层 Transformer)横跨 2 个节点:
节点 0:第 0 ~ 39 层
节点 1:第 40 ~ 79 层
→ 节点 0 处理完前 40 层,把激活值传给节点 1
→ 节点 1 接着处理后 40 层

核心特征:节点间只传递激活值(远小于权重),通信量小;但单个请求要顺序经过两个节点,存在流水线气泡

如何选择

vLLM 官方给出了明确的决策规则:

python 复制代码
决策树:

模型能放进单 GPU?
  → 是:不需要并行,直接单卡跑
  → 否 ↓

模型能放进单节点(多 GPU)?
  → 是:用 Tensor Parallel(单节点内 NVLink 带宽高)
        tp_size = 节点内 GPU 数
  → 否 ↓

需要跨节点?
  → 标准做法:TP 处理节点内,PP 处理节点间
        tp_size = 每节点 GPU 数
        pp_size = 节点数

特殊情况:单节点内 GPU 数量不能整除模型层数?
  → 用 PP(PP 支持不均等分层)
        tp_size = 1,pp_size = GPU 总数

一句话记住TP 用于节点内(高带宽互联),PP 用于节点间(带宽较低的跨节点)


二、环境准备:多机配置的前提检查清单

动手部署之前,先在所有节点上逐项检查这个清单。跳过任何一项,大概率后面要花数倍时间排查。

python 复制代码
# ============ 在每个节点上分别执行 ============

# 1. 验证 GPU 可见性
nvidia-smi -L
# 期望:列出所有 GPU,确认数量和型号一致

# 2. 验证 CUDA 版本一致(版本不一致会有奇怪的行为)
nvcc --version
python3 -c "import torch; print(torch.version.cuda)"

# 3. 验证节点间网络连通性(替换为实际 IP)
ping -c 4 <另一节点 IP>

# 4. 验证 InfiniBand / RDMA(如果有 IB 网卡)
ibstat | grep -E "State|Rate"
# 期望:State: Active,Rate: 200(HDR)或 100(EDR)

# 5. 验证 NCCL 能跨节点通信
NCCL_DEBUG=INFO python3 -c "
import torch, torch.distributed as dist, os
os.environ['MASTER_ADDR'] = '<头节点 IP>'
os.environ['MASTER_PORT'] = '29500'
os.environ['RANK'] = '0'  # 工作节点改为 1
os.environ['WORLD_SIZE'] = '2'
dist.init_process_group('nccl', timeout=__import__('datetime').timedelta(seconds=30))
print('NCCL 初始化成功')
"

# 6. 验证 SSH 无密码互访(Ray 需要)
ssh <另一节点 IP> "hostname"
# 期望:直接返回主机名,不需要输密码

# 7. 验证模型文件路径一致(每个节点必须能访问同一路径的模型权重)
ls /data/models/Qwen3.5-72B-Instruct/
# 期望:所有节点输出相同的文件列表

三、Ray 集群启动

多机部署强依赖 Ray,单节点多卡可以用 multiprocessing,但跨节点只能用 Ray。

标准启动流程

python 复制代码
# ==================== 头节点 ====================
# 设置网络接口(必须是节点间互通的那张网卡)
export NCCL_SOCKET_IFNAME=ib0        # InfiniBand 网卡
# export NCCL_SOCKET_IFNAME=eth0    # 以太网备选
export GLOO_SOCKET_IFNAME=ib0
export RAY_NETWORK_INTERFACE=ib0

ray start --head \
  --node-ip-address=<头节点 IP> \
  --port=6379 \
  --num-gpus=8

# ==================== 所有工作节点 ====================
export NCCL_SOCKET_IFNAME=ib0
export GLOO_SOCKET_IFNAME=ib0
export RAY_NETWORK_INTERFACE=ib0

ray start \
  --address="<头节点 IP>:6379" \
  --node-ip-address=<本节点 IP> \
  --num-gpus=8

# ==================== 在头节点验证集群状态 ====================
ray status
# 期望输出(2 节点 × 8 GPU 示例):
# Active: 2 nodes
# Total Usage: 0.0/16.0 GPU

启动 vLLM(在头节点执行)

python 复制代码
# 2 节点 × 8 GPU = 16 GPU 总计
# Qwen3.5-72B:TP=8(节点内),PP=2(节点间)

export VLLM_HOST_IP=<头节点 IP>

vllm serve /data/models/Qwen3.5-72B-Instruct \
  --served-model-name qwen3.5-72b \
  --tensor-parallel-size 8 \
  --pipeline-parallel-size 2 \
  --distributed-executor-backend ray \
  --dtype bfloat16 \
  --max-model-len 32768 \
  --gpu-memory-utilization 0.88 \
  --trust-remote-code

四、10 个真实踩坑

坑1:NCCL 卡住不动,没有错误日志,等 300 秒后 timeout

现象:启动命令一切正常,日志显示各个 Worker 初始化中,然后在某个位置停住,几分钟后出现:

java 复制代码
ncclCommInitRank: timeout waiting for ...
torch.distributed.DistBackendError: NCCL error ...

根本原因 :NCCL 在 ncclCommInitRank 阶段需要所有节点的 GPU 互相握手,如果节点间网络配置不对(防火墙、网卡未指定、端口被占),握手永远无法完成。

诊断步骤

python 复制代码
# 第一步:开启 NCCL 详细日志,看卡在哪里
NCCL_DEBUG=TRACE vllm serve ... 2>&1 | head -200
# 如果看到 "NCCL INFO Net/IB" 但没有 "Connected" → IB 网卡问题
# 如果看到 "NCCL INFO NET/Socket" → 没走 InfiniBand,走的是以太网

# 第二步:检查防火墙(NCCL 需要开放 29400~29500 范围的端口)
sudo ufw status
# 如果防火墙开着,临时关闭测试
sudo ufw disable

# 第三步:确认 NCCL_SOCKET_IFNAME 指向了正确的网卡
ip addr show
# 找出节点间互通的网卡名(通常是 ib0 或 eth0)

修复

python 复制代码
# 必须在所有节点上设置相同的环境变量,然后重启 Ray
export NCCL_SOCKET_IFNAME=ib0    # 替换为你的实际网卡名
export NCCL_IB_DISABLE=0         # 有 IB 时确保启用
export NCCL_IB_GID_INDEX=3       # IB 网卡的 GID 索引,视配置调整

# 增大 NCCL 初始化超时(慢速下载环境)
# 在 vllm serve 命令里加
--distributed-timeout 1800       # 默认 600s,下载大模型权重时可能不够

坑2:Ray 头节点自动占用 GPU,工作节点 GPU 数量统计错误

现象ray status 显示总 GPU 数少了 8 块,或者 vLLM 启动时报 Not enough GPUs,但 nvidia-smi 上明明有足够的 GPU。

原因 :Ray 的 Head Node 默认也会声明 GPU 资源(num-gpus=8),这导致 Ray 把头节点的 GPU 同时分配给了 Ray 的调度任务和 vLLM 的推理任务,产生资源竞争。

修复:头节点的 Ray 进程不分配 GPU:

python 复制代码
# ✅ 头节点:num-gpus=0,不占用 GPU
ray start --head \
  --node-ip-address=<头节点 IP> \
  --port=6379 \
  --num-gpus=0    # 关键:头节点不持有 GPU 资源

# ✅ 工作节点(包括头节点所在机器):单独启动 worker
ray start \
  --address="localhost:6379" \
  --node-ip-address=<头节点 IP> \
  --num-gpus=8

坑3:每个节点的模型路径不一致,Worker 加载失败

现象 :头节点日志正常,但工作节点的 Ray Worker 报 FileNotFoundError: model path not found

原因 :vLLM 的每个 Worker 进程都要独立加载模型权重,路径必须在所有节点上完全一致。这个问题在容器和裸机部署时表现不同:容器里很容易用 -v 挂载一致路径,裸机环境往往模型放在不同位置。

修复方案一(推荐):NFS 共享存储,所有节点挂载同一路径:

python 复制代码
# 在头节点建立 NFS 共享
sudo apt install nfs-kernel-server
echo "/data/models *(rw,sync,no_subtree_check)" >> /etc/exports
sudo exportfs -a

# 在所有工作节点挂载
sudo mount <头节点 IP>:/data/models /data/models

修复方案二 :使用 vLLM 官方提供的 run_cluster.sh,用 Docker 统一镜像和挂载点:

python 复制代码
# 官方脚本:vllm/examples/online_serving/run_cluster.sh
# 头节点
bash run_cluster.sh \
  vllm/vllm-openai:v0.18.0 \  # 相同镜像
  <头节点 IP> \
  --head \
  /data/models:/data/models    # 统一挂载路径

# 工作节点
bash run_cluster.sh \
  vllm/vllm-openai:v0.18.0 \
  <头节点 IP> \
  --worker \
  /data/models:/data/models

坑4:PP 模式下 pipeline_parallel_size 和实际节点数不匹配

现象 :设置了 --pipeline-parallel-size 2 但只有 1 个节点,或者 Ray 集群有 3 个节点但只用了 2 个,剩余节点资源空置。

原因理解 :vLLM 的 PP 把模型按层分成 pp_size 段,每段分配到一个独立的 GPU 组。如果 Ray 集群的实际节点数多于 pp_size,多余节点的 GPU 不会被使用。

python 复制代码
# 典型正确配置(2 节点 × 8 GPU)
vllm serve ... \
  --tensor-parallel-size 8 \   # 节点内 8 卡 TP
  --pipeline-parallel-size 2   # 2 个节点 PP

# 等价的纯 TP 配置(需要节点间高带宽 IB)
vllm serve ... \
  --tensor-parallel-size 16    # 跨节点 16 卡 TP,不用 PP

# 何时选哪个?
# IB 带宽充足(HDR 200Gb)→ 纯 TP,延迟更低
# IB 带宽一般(25GbE 以太网)→ TP+PP 组合,通信量少

坑5:PP 模式流水线气泡导致 GPU 利用率低

现象 :开启 PP 后,nvidia-smi 显示工作节点的 GPU 利用率只有 50~60%,第 0 段节点在计算,第 1 段节点在等待。

原因:这是流水线并行的固有问题。当 Micro-batch 不够多时,后段的 GPU 要等前段计算完才能工作------这段等待时间叫"流水线气泡"。

python 复制代码
时间轴:
节点0(层 0-39): [计算 req1] [计算 req2] [计算 req3] ...
节点1(层40-79):             [计算 req1] [计算 req2] ...
                 ↑ 节点1 在等节点0,这段时间是"气泡"

缓解方法

python 复制代码
# 方法一:增大并发请求数,让流水线更满
vllm serve ... \
  --max-num-seqs 256           # 增大并发,让流水线持续有数据

# 方法二:启用 Chunked Prefill,让 Prefill 和 Decode 交替执行
vllm serve ... \
  --enable-chunked-prefill \
  --max-num-batched-tokens 2048

# 方法三(vLLM 0.18 新特性):使用 --performance-mode throughput
# 这个模式内置了批次优化策略,自动减少气泡
vllm serve ... \
  --performance-mode throughput \
  --pipeline-parallel-size 2

坑6:Ray Worker 在请求过程中崩溃,Socket closed 错误

现象:服务启动正常,能处理一段时间的请求,但在处理了 100~5000 个请求后崩溃,日志出现:

复制代码
(RayWorkerWrapper pid=xxx) Error pushing mutable object:
RPC Error message: Socket closed; rpc_code: 14

原因:这是 vLLM + Ray Compiled DAG 在高并发多节点场景下的已知稳定性问题(GitHub Ray #59404),在 A100 和 H100 集群上均有复现。

临时缓解

python 复制代码
# 方法一:关闭 Ray Compiled DAG,改用标准通信
export VLLM_USE_RAY_COMPILED_DAG=0

# 方法二:改用共享内存通信(可以服务更多请求再崩溃)
export VLLM_USE_RAY_COMPILED_DAG_CHANNEL_TYPE=shm

# 方法三:限制最大并发数,降低通信压力
vllm serve ... \
  --max-num-seqs 64   # 保守值,视机型调整

# 方法四:加进程保活脚本

自动重启保活(生产环境必备):

python 复制代码
# restart_vllm.sh
#!/bin/bash
while true; do
  echo "[$(date)] 启动 vLLM..."
  vllm serve /data/models/Qwen3.5-72B-Instruct \
    --tensor-parallel-size 8 \
    --pipeline-parallel-size 2 \
    --distributed-executor-backend ray \
    # ... 其他参数
  
  EXIT_CODE=$?
  echo "[$(date)] vLLM 退出,退出码=${EXIT_CODE},5 秒后重启..."
  sleep 5
done

坑7:RDMA / InfiniBand 配置后回退到 Gloo,性能极差

现象 :明明配置了 InfiniBand,但 NCCL 日志里显示 Using Gloo,节点间通信带宽只有几 Gb/s,推理延迟极高。

原因:NCCL 会在 IB 初始化失败时静默回退到 Gloo(以太网慢速通信),而不是报错退出。常见原因是 GID Index 配置不对或者 IB 驱动未正确安装。

诊断和修复

python 复制代码
# 确认 IB 网卡状态
ibstat
ibv_devinfo | grep -E "port_state|active_mtu|gid"

# 找到正确的 GID Index
for i in $(seq 0 10); do
  echo -n "GID $i: "
  show_gids | grep "mlx5_0" | awk "NR==$((i+1)) {print}"
done
# 找到 RoCE v2 类型的 GID,记下 Index

# 设置正确的 GID Index(通常是 3,但每台机器可能不同)
export NCCL_IB_GID_INDEX=3
export NCCL_IB_DISABLE=0
export NCCL_NET_GDR_LEVEL=2     # 开启 GPU Direct RDMA

# 验证是否真正走了 IB
NCCL_DEBUG=INFO vllm serve ... 2>&1 | grep "NCCL INFO NET"
# 期望看到:NCCL INFO NET/IB : Using [mlx5_0:1]
# 如果看到:NCCL INFO NET/Socket → 没走 IB

坑8:多节点模型内存计算错误,实际显存不够

现象:理论上显存够(72B × 2 bytes ÷ 16 GPU ≈ 9GB/卡),但启动时仍然 OOM:

python 复制代码
torch.cuda.OutOfMemoryError: CUDA out of memory

原因:vLLM 的显存预算包含三部分:模型权重 + KV Cache + 激活值缓冲。当混合使用 TP 和 PP 时,由于 PP 的中间激活值需要在节点间传输,每个节点实际需要的显存比纯理论值高 10~20%。

另外,MeluXina 的实测数据显示:在 TP+PP 混合部署 Llama-405B 时,显存利用率并不是在所有 GPU 间完全均衡的,某些节点可能比理论值多用 15% 显存。

修复

python 复制代码
# 降低 gpu-memory-utilization,给激活值和缓冲留出空间
vllm serve ... \
  --gpu-memory-utilization 0.80   # 从默认 0.90 降到 0.80

# 或者降低最大上下文长度,减少 KV Cache 占用
vllm serve ... \
  --max-model-len 8192            # 从 32768 降到 8192

# 查看实际显存分配
# 启动后在日志里搜索:
# INFO: # GPU blocks: xxx → 可用 KV Cache 块数
# INFO: Memory profiling results: xxx → 各部分显存分配详情

坑9:环境变量在 Ray Worker 里不生效

现象 :在头节点设置了 NCCL_SOCKET_IFNAME=ib0,但 NCCL 日志显示 Worker 进程用的是 eth0

原因:Ray Worker 是子进程,不会自动继承所有父进程的环境变量,尤其是 Ray 的 Worker 是在 Ray 启动时就 fork 的,后来设的环境变量不会传进去。

正确做法 :必须在 ray start 之前设置环境变量,或者通过 Ray 的运行时环境传递:

python 复制代码
# ❌ 错误:ray start 之后再设 env,Worker 看不到
ray start --head ...
export NCCL_SOCKET_IFNAME=ib0  # 太晚了!

# ✅ 正确方法一:ray start 前设置
export NCCL_SOCKET_IFNAME=ib0
export NCCL_IB_GID_INDEX=3
ray start --head ...

# ✅ 正确方法二:通过 --runtime-env 传递(推荐,显式可见)
ray start --head \
  --runtime-env='{"env_vars": {"NCCL_SOCKET_IFNAME": "ib0", "NCCL_IB_GID_INDEX": "3"}}' \
  ...

坑10:TP=16 跨节点纯 Tensor Parallel,首 Token 延迟反而比 TP=8+PP=2 更高

现象:把 TP 从节点内 8 卡改成跨节点 16 卡(纯 TP,不用 PP),理论上并行度更高,实际上 p95 TTFT 从 1.2s 上升到 2.8s。

原因:TP 在每一层都需要 AllReduce 同步,TP=16 意味着跨节点的 AllReduce 要走节点间网络。即使是 InfiniBand HDR(200Gb/s),跨节点 AllReduce 的延迟也是节点内 NVLink AllReduce 的 5~10 倍,这个延迟在每一层都累积。

以 Qwen3.5-72B(80 层)为例:

  • 节点内 NVLink AllReduce:~0.1ms/层 × 80 层 = 8ms
  • 跨节点 IB AllReduce:~0.8ms/层 × 80 层 = 64ms

这就是为什么 Red Hat 的实践文档明确指出:当节点间互联带宽有限时,用 PP 处理节点间通信,而不是让 TP 跨节点

python 复制代码
推荐配置(2 节点 × 8 GPU,IB HDR):
TP=8(节点内 NVLink),PP=2(节点间 IB)→ TTFT ~1.2s

不推荐:
TP=16(跨节点 IB AllReduce 每层)→ TTFT ~2.8s

五、完整启动脚本(2 节点生产环境)

python 复制代码
#!/bin/bash
# start_distributed_qwen35_72b.sh
# 在头节点执行,工作节点已提前加入 Ray 集群

set -e

# ========== 节点配置 ==========
HEAD_IP="10.0.0.1"
WORKER_IPS=("10.0.0.2")
MODEL_PATH="/data/models/Qwen3.5-72B-Instruct"
LOG_DIR="/var/log/vllm"

# ========== 网络配置 ==========
export NCCL_SOCKET_IFNAME=ib0
export NCCL_IB_DISABLE=0
export NCCL_IB_GID_INDEX=3
export NCCL_NET_GDR_LEVEL=2
export GLOO_SOCKET_IFNAME=ib0
export RAY_NETWORK_INTERFACE=ib0
export VLLM_HOST_IP=$HEAD_IP

mkdir -p $LOG_DIR

# ========== 启动 Ray 集群 ==========
echo "启动 Ray 集群..."

# 头节点 Ray(不持有 GPU)
ray start \
  --head \
  --node-ip-address=$HEAD_IP \
  --port=6379 \
  --num-gpus=0 \
  --runtime-env="{\"env_vars\": {
      \"NCCL_SOCKET_IFNAME\": \"ib0\",
      \"NCCL_IB_GID_INDEX\": \"3\"
  }}"

# 头节点的 GPU Worker
ray start \
  --address="localhost:6379" \
  --node-ip-address=$HEAD_IP \
  --num-gpus=8

# 等待工作节点加入(工作节点需手动提前执行 ray start --address=...)
echo "等待工作节点加入集群(30s)..."
sleep 30

# 验证集群状态
ray status
TOTAL_GPUS=$(ray status | grep "GPU" | grep "Total" | awk '{print $2}' | cut -d'/' -f2)
echo "集群总 GPU 数:$TOTAL_GPUS"

if [ "$TOTAL_GPUS" != "16" ]; then
  echo "❌ GPU 数量不对,期望 16,实际 $TOTAL_GPUS,请检查工作节点"
  exit 1
fi

# ========== 启动 vLLM ==========
echo "启动 vLLM 服务..."

exec vllm serve $MODEL_PATH \
  --served-model-name qwen3.5-72b \
  --host 0.0.0.0 \
  --port 8000 \
  --dtype bfloat16 \
  --tensor-parallel-size 8 \
  --pipeline-parallel-size 2 \
  --distributed-executor-backend ray \
  --distributed-timeout 1800 \
  --max-model-len 32768 \
  --gpu-memory-utilization 0.85 \
  --max-num-seqs 128 \
  --enable-prefix-caching \
  --performance-mode balanced \
  --trust-remote-code \
  2>&1 | tee -a $LOG_DIR/vllm_distributed.log

六、踩坑速查表

# 表现 关键修复
1 NCCL 握手超时 卡住 300s 后 timeout NCCL_SOCKET_IFNAME 指向正确网卡
2 头节点占用 GPU Ray GPU 数少 8 头节点 --num-gpus=0
3 模型路径不一致 Worker 找不到模型 NFS 共享或 Docker -v 统一挂载
4 PP size 配置错 节点资源浪费 pp_size = 节点数,tp_size = 节点内 GPU 数
5 PP 气泡利用率低 GPU 利用率 50~60% --max-num-seqs 256 + --enable-chunked-prefill
6 Ray Compiled DAG 崩溃 100~5000 请求后 Socket closed VLLM_USE_RAY_COMPILED_DAG=0 + 保活脚本
7 IB 回退到 Gloo 带宽极低,延迟高 检查 NCCL_IB_GID_INDEX
8 实际显存超出预估 OOM --gpu-memory-utilization 0.80
9 环境变量 Worker 不生效 NCCL 用错网卡 ray start 前设置或用 --runtime-env
10 跨节点纯 TP 反而慢 TTFT 比 TP+PP 高 2~3 倍 节点间走 PP,节点内走 TP

参考资料


多机分布式部署是 LLM 运维里最复杂的一关。踩坑的时候请记住:先排网络,再排 Ray,最后排 vLLM。90% 的多机问题都出在网络和环境一致性上,不是 vLLM 本身的 bug。如果遇到了本文没有覆盖的坑,欢迎评论区补充。

相关推荐
2501_9458374319 小时前
OpenAI Codex:重新定义软件工程的 AI 智能体
人工智能
直奔標竿19 小时前
Java开发者AI转型第二十三课!Spring AI个人知识库实战(二):异步ETL流水线搭建与避坑指南
java·人工智能·spring boot·后端·spring
zandy101119 小时前
重新定义AI测试——衡石科技从“用例通过“到“可信质量防线“的工程实践
人工智能·科技
奇思智算19 小时前
小白AI创作GPU算力平台测评:多平台对比与选择指南
大数据·人工智能·gpu算力·智星云·gpu算力租用
墨染天姬19 小时前
[AI]OPENAI的PPO算法
人工智能·算法
sheji10519 小时前
割草机器人行业市场分析报告
大数据·人工智能·microsoft
xixixi7777719 小时前
AI安全周记:AI驱动攻击占比50%、PQC国标落地、ShinyHunters连环袭击——面对1:25的攻防成本鸿沟,防守方还能撑多久?
人工智能·安全·ai·大模型·aigc·量子计算·供应链
生活观察站19 小时前
淄博抖音推广公司实测评测2026年更新:效果与性价比双维度对比
大数据·人工智能
oort12319 小时前
奥尔特云 VLStream 视觉 AI 平台采用 MIT 协议开源,贯通标注、训练、部署全流程,集成视频物联核心能力,支持私有化部署与多场景智能化应用
人工智能·开源
Bruce_Liuxiaowei20 小时前
企业国有资产法修订与县级融媒体资产管理的客观解读
人工智能·媒体