第一章:Go在字节跳动AI Infra中的破界实践
在字节跳动AI基础设施(AI Infra)体系中,Go语言已突破传统后端服务边界,深度嵌入模型训练调度、分布式推理网关、实时特征管道与可观测性数据采集等核心链路。其高并发模型、静态二进制分发能力及低GC延迟特性,成为支撑万卡级训练集群毫秒级任务编排的关键底座。
高性能推理网关的Go实现
字节自研的Triton兼容推理网关(InferGate)采用Go重构,通过net/http定制HTTP/2+gRPC双协议栈,并利用sync.Pool复用protobuf序列化缓冲区。关键优化包括:
- 使用
gorilla/mux构建细粒度路由,按模型版本+硬件类型(CUDA/ROCm)动态负载均衡; - 基于
context.WithTimeout实现端到端超时传递,避免长尾请求阻塞线程池; - 通过
pprof持续采样,将P99延迟从127ms压降至38ms。
// 示例:模型路由注册逻辑(简化)
func registerModelRouter(r *mux.Router, modelID string) {
r.HandleFunc("/v2/models/{model}/infer",
withTimeout(handleInference, 500*time.Millisecond)).Methods("POST")
}
分布式训练协调器的轻量级设计
替代原有Python-based调度器,Go协程驱动的Coordinator组件以单进程管理超10万Pod生命周期。其核心机制包括:
- 基于etcd Watch事件驱动状态机,避免轮询开销;
- 使用
runtime.LockOSThread()绑定GPU绑定型任务至指定OS线程; - 通过
go.uber.org/zap结构化日志,支持按job_id、node_ip多维检索。
| 指标 | Python调度器 | Go Coordinator |
|---|---|---|
| 单节点吞吐量 | 120 job/s | 2100 job/s |
| 内存常驻峰值 | 4.2GB | 680MB |
| 故障恢复平均耗时 | 8.3s | 127ms |
实时特征服务的内存安全实践
为规避C++ SDK的内存泄漏风险,特征服务SDK全面迁移至Go,借助unsafe.Pointer零拷贝对接Folly::fbstring底层,同时通过go:linkname绕过反射限制直接调用TensorRT C API——所有跨语言调用均经cgo沙箱校验,确保panic不穿透至宿主进程。
第二章:为什么字节跳动坚定选择Go重构AI胶水层
2.1 Python胶水层的性能瓶颈与运维债实证分析
数据同步机制
典型胶水层常通过 requests 轮询调度下游服务,引发高延迟与连接风暴:
# 同步调用示例(问题模式)
import requests
for task in tasks:
resp = requests.post("http://backend/api/process", json=task, timeout=30) # 阻塞式、无重试退避
if resp.status_code != 200:
log_error(task, resp.text)
逻辑分析:单线程串行阻塞调用,timeout=30 导致长尾延迟积压;缺乏熔断、指数退避与连接池复用,每请求新建 TCP 连接,加剧内核 socket 资源争用。
运维债量化表
| 指标 | 胶水层实测值 | 行业基线 | 偏差 |
|---|---|---|---|
| P99 响应延迟 | 4.2s | ≤200ms | +2000% |
| 日均异常重试次数 | 17,842 | +35,584% |
架构瓶颈路径
graph TD
A[Flask API] --> B[requests.post]
B --> C[DNS解析+TCP握手]
C --> D[后端服务排队]
D --> E[无背压反馈]
E --> A
改进方向
- 替换为异步
httpx.AsyncClient+ 连接池 - 引入
tenacity实现带 jitter 的指数退避 - 增加 Prometheus metrics 暴露
glue_request_duration_seconds
2.2 Go语言并发模型与内存安全对LLM服务的关键适配性
轻量级协程应对高并发推理请求
Go 的 goroutine + channel 模型天然契合 LLM 服务中大量并行 prompt 处理场景。单个 HTTP handler 启动 goroutine 执行模型推理,避免线程阻塞:
func handleInference(w http.ResponseWriter, r *http.Request) {
req := parseRequest(r) // 解析输入(prompt、参数)
ch := make(chan *Response, 1) // 缓冲通道防 goroutine 泄漏
go func() {
defer close(ch)
resp, err := llm.Run(req.Prompt, req.Temperature) // 实际调用推理引擎
if err != nil {
ch <- &Response{Error: err.Error()}
return
}
ch <- &Response{Text: resp}
}()
select {
case res := <-ch:
json.NewEncoder(w).Encode(res)
case <-time.After(30 * time.Second):
http.Error(w, "timeout", http.StatusGatewayTimeout)
}
}
逻辑分析:ch 使用容量为 1 的缓冲通道,确保 goroutine 不因接收方未就绪而永久挂起;select 带超时机制,防止长尾请求拖垮服务;llm.Run 需为线程安全实现——这直接依赖 Go 的内存安全约束(无裸指针、自动 GC)。
内存安全保障状态一致性
LLM 服务常需共享权重缓存与 tokenizer 实例。Go 的 sync.Once 与不可变数据结构组合可杜绝竞态:
| 机制 | 作用 | LLM 场景示例 |
|---|---|---|
sync.Pool |
复用 token 编码中间对象 | 减少 GC 压力,提升吞吐 |
atomic.Value |
安全更新模型版本句柄 | 热加载新模型权重而不中断服务 |
map + sync.RWMutex |
保护会话上下文缓存(如 conversation history) | 支持多轮对话状态隔离 |
并发错误处理范式
LLM 推理链路涉及网络调用、GPU kernel 启动、日志写入等异步环节。Go 的 context.Context 统一传播取消信号与超时:
graph TD
A[HTTP Request] --> B[Context with Timeout]
B --> C[Tokenize via sync.Pool]
B --> D[Dispatch to GPU Worker]
C --> E[Validate Input Length]
D --> F[Run CUDA Kernel]
E --> G[Early Reject if >4096 tokens]
F --> H[Post-process logits]
G & H --> I[Return Streaming Response]
2.3 字节内部Go生态基建成熟度:从Kratos到ByteDance-Go-SDK演进路径
字节跳动Go基础设施经历了从开源依赖(Kratos)到自研统一SDK的演进,核心驱动力是规模化微服务治理与多云/混合云部署需求。
架构演进关键节点
- 初期基于Kratos构建基础RPC与中间件能力,但存在配置分散、链路追踪埋点不一致问题
- 中期沉淀
go-common库,统一日志、metric、config抽象层 - 当前落地
ByteDance-Go-SDK,提供声明式客户端、自动重试策略及跨Region容灾兜底机制
数据同步机制
// ByteDance-Go-SDK v2.4+ 提供的声明式数据同步客户端
client := sdk.NewSyncClient(
sdk.WithRetryPolicy(sdk.RetryPolicy{
MaxAttempts: 3,
Backoff: sdk.ExpBackoff{BaseDelay: time.Millisecond * 100},
IsRetryable: func(err error) bool { return errors.Is(err, sdk.ErrTransient) },
}),
sdk.WithRegion("cn-east-1"),
)
该配置启用指数退避重试,IsRetryable精准识别瞬态错误(如网络抖动、临时限流),避免对业务侧暴露底层重试逻辑;WithRegion实现自动路由至就近数据中心,降低P99延迟37%。
生态兼容性对比
| 维度 | Kratos(2020) | ByteDance-Go-SDK(2023) |
|---|---|---|
| 配置中心支持 | Apollo仅限HTTP | 支持Apollo/Nacos/ZooKeeper统一适配器 |
| gRPC拦截器粒度 | 全局单一链 | 按Service/Method分级注册 |
graph TD
A[业务代码] --> B[SDK Client Interface]
B --> C{自动选择}
C --> D[本地缓存读取]
C --> E[跨Region主备同步]
C --> F[降级Mock服务]
2.4 工程效能对比:Go vs Python在千卡集群调度场景下的CI/CD吞吐量实测
实验环境配置
- 调度规模:1024 GPU卡(8×A100节点×16)
- CI负载:每轮构建含32个微服务镜像+12个模型训练任务
- 测量指标:单位时间成功交付流水线数(pipelines/min)
吞吐量实测数据
| 语言 | 平均吞吐量 | P95延迟 | 内存常驻峰值 | GC暂停总时长/分钟 |
|---|---|---|---|---|
| Go | 47.3 | 842 ms | 1.2 GB | 18 ms |
| Python | 22.1 | 2.1 s | 3.8 GB | 1.2 s |
核心调度器关键逻辑对比
// Go版调度器核心循环(简化)
func (s *Scheduler) run() {
for !s.shutdown {
select {
case task := <-s.taskQueue: // 无锁通道,O(1)入队
s.assignGPU(task) // 基于位图的GPU资源快速定位
case <-time.After(10ms): // 防活锁退避
}
}
}
该实现避免全局锁竞争,
taskQueue为无缓冲channel,配合assignGPU中预计算的GPU拓扑位图(uint64[16]),单次资源分配耗时稳定在12μs内。
# Python版等效逻辑(伪代码)
def run_scheduler():
while not shutdown_flag.is_set():
try:
task = task_queue.get(timeout=0.01) # GIL下阻塞式获取
gpu_id = find_available_gpu(task.req) # 线性扫描设备列表
assign_task(task, gpu_id)
except Empty:
continue
CPython的
queue.Queue.get()触发GIL争用,find_available_gpu需遍历1024项设备状态列表,平均耗时达83ms,成为吞吐瓶颈。
架构决策影响链
graph TD
A[语言运行时特性] –> B[并发模型]
B –> C[资源分配路径长度]
C –> D[单流水线端到端延迟]
D –> E[集群级CI/CD吞吐量]
2.5 团队认知升级:从“脚本思维”到“系统编程思维”的迁移方法论
脚本思维关注单点任务自动化,而系统编程思维强调可观测性、容错边界与模块契约。迁移需三步落地:
认知锚点重构
- ✅ 拒绝“能跑就行”,定义接口契约(输入/输出/错误码/超时)
- ✅ 将日志视为结构化事件流,而非调试辅助
- ✅ 所有依赖必须显式声明版本与健康探针
示例:从脚本式重试到弹性策略
# ❌ 脚本思维:裸循环+sleep
for _ in range(3):
try:
resp = requests.get("https://api.example.com/data")
break
except:
time.sleep(1)
# ✅ 系统思维:带退避、熔断、上下文追踪的客户端
from tenacity import retry, stop_after_attempt, wait_exponential
@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=1, max=10))
def fetch_data():
with tracer.start_as_current_span("api.fetch"): # OpenTelemetry上下文
return httpx.get("https://api.example.com/data", timeout=5.0)
逻辑分析:tenacity 提供指数退避(min=1, max=10 控制重试间隔上限),避免雪崩;timeout=5.0 显式设服务边界;OpenTelemetry span 实现跨服务链路追踪,将调用纳入全局可观测体系。
迁移成熟度对照表
| 维度 | 脚本思维 | 系统编程思维 |
|---|---|---|
| 错误处理 | except: pass |
分类捕获 + 降级策略 + 告警触发 |
| 配置管理 | 硬编码或环境变量 | 动态加载 + Schema校验 + 变更审计 |
| 依赖治理 | pip install -r reqs.txt |
容器镜像锁版本 + SBOM生成 + CVE扫描 |
graph TD
A[原始脚本] --> B[提取核心逻辑]
B --> C[封装为带契约的模块]
C --> D[注入监控/限流/重试能力]
D --> E[接入服务注册与配置中心]
第三章:大模型推理服务Go化核心架构设计
3.1 基于Go net/http+fasthttp混合协议栈的低延迟请求路由设计
在高并发网关场景中,net/http 提供稳定性与生态兼容性,而 fasthttp 以零内存分配和复用连接实现极致吞吐。混合协议栈通过分层路由实现能力互补。
路由决策策略
- 请求路径匹配
/api/v1/realtime→ fasthttp 处理(亚毫秒级) - 其他路径(如
/admin,/webhook)→ net/http 处理(支持中间件链)
// 混合监听器启动示例
go func() {
log.Fatal(fasthttp.ListenAndServe(":8081", realtimeHandler)) // fasthttp专用端口
}()
http.ListenAndServe(":8080", standardMux) // net/http主入口
该双端口设计规避了协议栈混用的类型不安全问题;:8081 专用于低延迟通道,避免标准库 TLS/HTTP/2 开销。
性能对比(1K 并发,p99 延迟)
| 协议栈 | p99 延迟 | 内存分配/req |
|---|---|---|
| net/http | 12.4ms | 18.2 KB |
| fasthttp | 0.8ms | 0 B (复用) |
| 混合路由 | 1.2ms* | 2.1 KB |
*含 DNS+TLS 终结开销后的实测值
graph TD
A[Client] -->|Host: api.example.com| B{LB}
B -->|Path starts with /realtime| C[fasthttp :8081]
B -->|Other paths| D[net/http :8080]
C --> E[Zero-copy JSON parser]
D --> F[Middleware stack]
3.2 TensorRT/ONNX Runtime Go绑定层的零拷贝内存管理实践
零拷贝内存管理是 Go 与 C++ 推理引擎(TensorRT/ONNX Runtime)高效协同的关键。核心在于复用 Go 的 unsafe.Pointer 与 C 的 void*,绕过 Go runtime 的 GC 管理和内存复制。
数据同步机制
需确保 Go slice 底层数据与 C 端 tensor 内存地址完全一致,且生命周期由 C 端显式控制:
// 创建与 TensorRT 共享的 pinned 内存
ptr := C.cudaMallocHost(C.size_t(size)) // 锁页内存,支持 DMA 直传
slice := (*[1 << 30]byte)(ptr)[:size:size]
cudaMallocHost分配的锁页内存可被 GPU 直接访问;[:size:size]保证 Go 不扩展底层数组,避免 GC 移动;unsafe.Pointer(ptr)可直接传入TRT::IExecutionContext::enqueueV2()。
内存生命周期对照表
| 阶段 | Go 端操作 | C 端责任 |
|---|---|---|
| 分配 | C.cudaMallocHost |
TensorRT 引擎接管 |
| 推理中 | unsafe.Slice(ptr, len) |
绑定至 IExecutionProvider |
| 释放 | C.cudaFreeHost(ptr) |
必须在所有 stream 同步后调用 |
关键约束流程
graph TD
A[Go 分配 cudaMallocHost] --> B[传 ptr 给 ONNX Runtime SetInput]
B --> C[推理执行 enqueueV2]
C --> D{GPU stream 同步完成?}
D -->|Yes| E[C.cudaFreeHost]
D -->|No| C
3.3 多级缓存协同:LRU-GC感知缓存 + GPU显存页表映射的Go实现
核心设计思想
将 CPU 端 LRU 缓存与 GPU 显存生命周期深度耦合,通过 GC 触发时机主动驱逐已卸载显存页对应的键值对,避免悬空引用。
LRU-GC 感知缓存结构
type LRUGCCache struct {
cache *lru.Cache
gcHook func(key interface{}) // GC前回调:检查GPU页表是否仍驻留
}
gcHook 在每次 runtime.GC() 前被注入,依据 key 查询 GPU 页表(通过 CUDA cuMemGetAttribute),仅当页未被释放时保留缓存项。
GPU页表映射关键字段
| 字段 | 类型 | 说明 |
|---|---|---|
va |
uint64 |
虚拟地址(GPU VA) |
pa |
uint64 |
物理页帧号(PFN) |
refCount |
int32 |
CPU/GPU 引用计数 |
协同流程
graph TD
A[CPU请求数据] --> B{缓存命中?}
B -->|是| C[直接返回]
B -->|否| D[分配GPU显存页]
D --> E[建立VA→PA映射]
E --> F[插入LRU-GC缓存]
F --> G[GC触发时调用gcHook校验页存活]
- 缓存驱逐策略:
OnEvict中同步调用cuMemFree(若页仍有效) - 显存页生命周期由
runtime.SetFinalizer绑定到 GPU 内存句柄
第四章:端到端延迟优化的Go工程落地细节
4.1 GC调优实战:GOGC=20 + runtime.LockOSThread在KV Cache预分配中的应用
KV缓存初始化阶段的GC压力痛点
高频写入场景下,KV Cache初始填充易触发频繁堆分配与GC停顿,尤其在make([]byte, size)批量分配时。
GOGC=20的精准压制
GOGC=20 go run main.go
将GC触发阈值从默认100降至20,使堆增长至当前活跃堆2倍即触发回收,显著减少单次GC扫描量,降低STW时间约40%(实测P99延迟从12ms→7ms)。
绑定OS线程保障内存局部性
func initCache() {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
cache = make(map[string][]byte, 1e6) // 预分配哈希桶
}
LockOSThread阻止goroutine跨线程迁移,配合NUMA感知内存分配器,提升TLB命中率与缓存行利用率。
| 参数 | 默认值 | 推荐值 | 效果 |
|---|---|---|---|
GOGC |
100 | 20 | 更早、更轻量GC循环 |
GOMEMLIMIT |
unset | 8GiB | 防止OOM突刺 |
graph TD
A[启动KV Cache] --> B[GOGC=20生效]
B --> C[首次分配触发GC]
C --> D[LockOSThread绑定CPU核心]
D --> E[连续内存页分配]
E --> F[缓存命中率↑ 35%]
4.2 异步Pipeline编排:基于chan+select构建的Tokenizer→Prefill→Decode流水线
核心设计思想
以无锁、非阻塞方式串联模型推理三阶段:Tokenizer(输入分词)、Prefill(首token计算)、Decode(自回归生成),各阶段通过带缓冲通道解耦,select 实现超时控制与多路复用。
数据同步机制
type PipelineStage struct {
in, out chan *Request
done chan struct{}
}
func (s *PipelineStage) Run(process func(*Request)) {
for {
select {
case req := <-s.in:
process(req)
s.out <- req
case <-s.done:
return
}
}
}
in/out 为容量为16的带缓冲通道,避免阶段间强耦合;done 支持优雅退出;process 封装具体计算逻辑(如调用CUDA kernel)。
阶段协作时序
| 阶段 | 输入依赖 | 输出目标 | 典型耗时 |
|---|---|---|---|
| Tokenizer | 原始文本 | token IDs | ~1ms |
| Prefill | token IDs | KV Cache + logits | ~50ms |
| Decode | previous logits | next token ID | ~5ms/token |
执行流图
graph TD
A[Tokenizer] -->|token IDs| B[Prefill]
B -->|KV Cache + logits| C[Decode]
C -->|next token| C
C -->|final output| D[Response]
4.3 内核级优化:eBPF辅助的Go协程调度延迟观测与CPU亲和性绑定
eBPF观测点注入
通过 bpf_link 在 __schedule 和 gopark 处挂载跟踪点,捕获 Goroutine 阻塞前的 TID、P ID 及就绪等待时长:
// trace_sched_delay.c(简化)
SEC("tracepoint/sched/sched_migrate_task")
int trace_migration(struct trace_event_raw_sched_migrate_task *ctx) {
u64 pid = bpf_get_current_pid_tgid() >> 32;
u64 ts = bpf_ktime_get_ns();
bpf_map_update_elem(&sched_start, &pid, &ts, BPF_ANY);
return 0;
}
逻辑:利用 sched_migrate_task 跟踪迁移起点,结合 bpf_ktime_get_ns() 精确打点;&sched_start 是 BPF_MAP_TYPE_HASH,键为 PID,值为纳秒级时间戳。
Go 运行时亲和性控制
runtime.LockOSThread()
cpu := uint32(2)
syscall.SchedSetaffinity(0, &cpu)
LockOSThread()绑定 M 到当前 OS 线程SchedSetaffinity将线程强制限定在 CPU 2
观测数据对比(μs)
| 场景 | 平均调度延迟 | P99 延迟 |
|---|---|---|
| 默认调度 | 182 | 417 |
| eBPF+CPU2 绑定 | 43 | 89 |
graph TD A[Goroutine Park] –> B{eBPF tracepoint} B –> C[记录入队时间] C –> D[Go runtime 设置 CPU affinity] D –> E[内核调度器定向投递]
4.4 混合部署验证:Go服务与CUDA容器共置下的NUMA感知内存分配策略
在混合部署场景中,Go应用(低延迟API网关)与CUDA加速容器(如TensorRT推理服务)共享物理节点时,跨NUMA节点的内存访问将导致显著带宽衰减与延迟抖动。
NUMA绑定策略实施
通过numactl与容器运行时参数协同控制:
# 启动CUDA容器:绑定至NUMA Node 1,强制本地内存分配
numactl --cpunodebind=1 --membind=1 \
docker run --rm --gpus all -v /dev/shm:/dev/shm \
--ulimit memlock=-1 --ulimit stack=67108864 \
-e NVIDIA_VISIBLE_DEVICES=0 \
nvcr.io/nvidia/tensorrt:24.07-py3 \
python infer.py
逻辑分析:
--membind=1确保所有malloc及GPU pinned memory均从Node 1内存池分配;--cpunodebind=1使CUDA上下文线程亲和于同节点CPU核心,避免跨节点PCIe流量。--ulimit stack防止大模型加载时栈溢出触发OOM Killer。
Go服务内存对齐配置
启用GODEBUG=madvdontneed=1并配合runtime.LockOSThread()保障goroutine NUMA局部性。
| 组件 | NUMA策略 | 关键参数 |
|---|---|---|
| Go HTTP Server | CPU/memory绑核 | taskset -c 4-7, numactl --membind=0 |
| CUDA Container | 显存+主机内存双绑定 | --membind=1, CUDA_VISIBLE_DEVICES=0 |
graph TD
A[Go服务启动] --> B[调用numactl --membind=0]
C[CUDA容器启动] --> D[GPU驱动分配pinned memory]
D --> E{是否同NUMA node?}
E -->|否| F[带宽下降38%, p99延迟↑210ms]
E -->|是| G[PCIe直达+本地内存,吞吐提升2.3x]
第五章:从单点突破到AI Infra范式迁移
过去三年,某头部电商公司在推荐系统迭代中经历了典型的技术演进路径:初期仅在离线训练环节引入PyTorch 1.10+分布式训练(DDP),单点优化AUC提升0.8%;但线上推理延迟波动达±320ms,AB测试分流不均问题频发。这暴露了“模型孤岛”困境——算法团队交付的模型无法被SRE与MLOps团队无缝接管。
工程化瓶颈倒逼架构重构
该公司于2023年Q2启动AI Infra统一底座建设,核心动作包括:
- 将Kubernetes集群升级至v1.28,启用Device Plugin管理NVIDIA A100/A800显卡资源池;
- 构建标准化模型服务契约(Model Contract v2.1),强制要求所有上线模型提供
/health,/predict,/metadata三类API端点; - 引入Ray Serve替代原有Flask微服务,支持动态扩缩容与蓝绿发布。
数据闭环驱动基础设施演进
下表对比了重构前后关键指标变化:
| 维度 | 重构前 | 重构后 | 改进幅度 |
|---|---|---|---|
| 模型上线周期 | 5.2天 | 4.7小时 | ↓96.2% |
| GPU资源碎片率 | 38% | 11% | ↓71% |
| 推理P99延迟 | 412ms | 89ms | ↓78.4% |
多模态训练负载的基础设施适配
当视觉大模型(ViT-H/14)接入训练平台时,原生K8s调度器无法感知显存拓扑关系。团队通过自定义Scheduler Extender实现GPU NUMA感知调度,并集成NVIDIA DCGM Exporter采集显存带宽、NVLink吞吐等17项硬件指标。以下为实际部署的Pod资源配置片段:
resources:
limits:
nvidia.com/gpu: 4
# 显式声明NUMA亲和性
device-plugin.nvidia.com/numa-node: "0"
混合精度训练的稳定性保障
FP16训练引发梯度溢出问题曾导致37%的Job失败。Infra团队在CUDA Graph封装层注入自动Loss Scaling模块,并基于Prometheus指标构建动态重试策略:当nv_gpu_utilization{job="train"} > 95%持续2分钟,自动触发学习率衰减+梯度裁剪双保险机制。
模型即代码的落地实践
所有生产环境模型均通过GitOps流程管理,其CI/CD流水线包含硬性校验规则:
- 模型权重文件必须通过SHA256签名验证;
- ONNX Runtime推理图需通过TensorRT 8.6.1编译验证;
- 每次提交触发全链路性能回归测试(含CPU/GPU/PYNQ-FPGA三端基准)。
flowchart LR
A[Git Commit] --> B{CI Pipeline}
B --> C[ONNX Schema Validation]
B --> D[NVLink Bandwidth Benchmark]
C --> E[Auto-Quantize to INT8]
D --> F[Fail if < 18GB/s]
E --> G[Deploy to Canary Cluster]
F --> G
G --> H[Prometheus SLO Check]
H --> I{{SLO达标?}}
I -->|Yes| J[Rollout to Prod]
I -->|No| K[Rollback & Alert]
该范式迁移使跨团队协作接口从“人肉对接”转向契约化治理,算法工程师提交的model.yaml可直接触发从数据准备、训练、验证到灰度发布的全生命周期。Infra团队将GPU利用率基线从31%提升至68%,同时支撑日均新增模型版本127个。
