执行摘要
- 一句话:为 gRPC 模式添加 HTTP sidecar 端点和 FlushCache RPC
- 推荐动作:建议关注以下设计决策:
- profiling 端点放在 sidecar 而非 gRPC:PD 模式需要 per-worker 定向,不应通过 router fan-out。
- FlushCache 作为 gRPC RPC:需要 fan-out 到所有 worker,因此通过 router 调度是合理的选择。
- 移除重复端点:review 中及时删除了 sidecar 中多余的 /server_info,保持了单一实现。
这些决策体现了对异构传输模式下功能划分的清晰思考,值得在类似场景复用。
功能与动机
gRPC 模式之前缺乏 profiling、缓存管理和服务器内省端点,阻碍了 torch profiler 工作流与 bench_serving.py 对 gRPC 部署的使用。PR body 明确提到:“gRPC mode previously lacked profiling, cache management, and server introspection endpoints. This blocked: Torch profiler workflows… bench_serving.py and bench_one_batch_server against gRPC deployments”。
实现拆解
- 重构现有 metrics 服务为通用 sidecar:将原来独立的
_start_metrics_server 函数拆分为 _start_sidecar_server(通用启动逻辑)、_add_metrics_routes(添加 /metrics 路由)和 _check_communicator_results(结果校验辅助函数),使 sidecar 可承载多个端点。
- 新增 profiling 端点:在
_add_admin_routes 中注册 /start_profile 和 /stop_profile 两个 POST 端点。start_profile_handler 解析 JSON 请求体(含环境变量覆盖逻辑,如 SGLANG_PROFILE_WITH_STACK),构造 ProfileReq 对象,通过 request_manager.send_communicator_req 发送给 scheduler,并处理响应错误。超时设置为 600 秒。
- gRPC FlushCache 集成:通过依赖的
smg-grpc-servicer 包新增 FlushCache RPC,router 在收到 HTTP /flush_cache 请求时对 gRPC worker 调用该 RPC,实现所有 worker 的缓存刷新。
- 启动流程调整:
serve_grpc 函数现在无条件启动 HTTP sidecar(不再仅当 --enable-metrics 时才启动),_on_request_manager_ready 回调用于在 gRPC request manager 就绪后将 sidecar 的 app 传给 router。
- 服务器参数变更:将
metrics_http_port 字段重命名为 grpc_http_sidecar_port,CLI 参数同步更改,并更新帮助文本以体现新用途。
关键文件:
python/sglang/srt/entrypoints/grpc_server.py(模块 gRPC服务;类别 source;类型 dependency-wiring;符号 _start_sidecar_server, _add_metrics_routes, _check_communicator_results, _add_admin_routes): 核心变更文件,完成 HTTP sidecar 框架搭建、profiling 端点实现、启动流程调整,是本次 PR 的主要逻辑所在。
python/sglang/srt/server_args.py(模块 配置参数;类别 source;类型 configuration): 将 --metrics-http-port 重命名为 --grpc-http-sidecar-port,反映 sidecar 的新用途(不仅提供 metrics,还提供 profiling 端点)。
关键符号:_start_sidecar_server, _add_metrics_routes, _check_communicator_results, _add_admin_routes, start_profile_handler, stop_profile_handler, _on_request_manager_ready
关键源码片段
python/sglang/srt/entrypoints/grpc_server.py
核心变更文件,完成 HTTP sidecar 框架搭建、profiling 端点实现、启动流程调整,是本次 PR 的主要逻辑所在。
# python/sglang/srt/entrypoints/grpc_server.py
# HTTP sidecar 核心框架
def _add_admin_routes(app, request_manager):
"""添加 /start_profile、/stop_profile 等 admin 端点。
Business logic(请求构造、环境变量处理、响应解释)在此处;
request_manager 仅提供与 scheduler 的通信传输。
"""
async def start_profile_handler(request):
try:
# 解析 JSON body,允许空 body
if request.content_length and request.content_length > 0:
try:
body = await request.json()
except json.JSONDecodeError as e:
return web.Response(status=400, text=f"Invalid JSON: {e}")
else:
body = {}
# 环境变量覆盖逻辑(与 tokenizer_communicator_mixin 一致)
with_stack = body.get("with_stack")
env_with_stack = get_bool_env_var("SGLANG_PROFILE_WITH_STACK", "true")
with_stack = (with_stack is not False) and env_with_stack
record_shapes = body.get("record_shapes")
env_record_shapes = get_bool_env_var("SGLANG_PROFILE_RECORD_SHAPES", "true")
record_shapes = (record_shapes is not False) and env_record_shapes
# 构造 ProfileReq,通过 communicator 发送给 scheduler
req = ProfileReq(
type=ProfileReqType.START_PROFILE,
output_dir=body.get("output_dir"),
start_step=body.get("start_step"),
num_steps=body.get("num_steps"),
activities=body.get("activities"),
with_stack=with_stack,
record_shapes=record_shapes,
profile_by_stage=body.get("profile_by_stage", False),
profile_id=str(time.time()),
merge_profiles=body.get("merge_profiles", False),
profile_prefix=body.get("profile_prefix"),
profile_stages=body.get("profile_stages"),
)
# 超时 600 秒以支持长时间 profiling
results = await request_manager.send_communicator_req(
req, "profile_communicator", timeout=600.0
)
err = _check_communicator_results(results, "Start Profile")
if err:
return err
return web.Response(text="Start profiling.\n")
except Exception as e:
logger.exception("Failed to start profile")
return web.Response(status=500, text="Internal error")
# 类似实现 stop_profile_handler,此处省略
app.router.add_post("/start_profile", start_profile_handler)
app.router.add_post("/stop_profile", stop_profile_handler)
评论区精华
Review 中主要讨论点:
风险与影响
关联脉络
- PR #1088 feat(grpc): add FlushCache RPC and profiling support for gRPC mode: 对等 PR,需要在 smg-grpc-servicer 中添加 FlushCache RPC 和 request_manager 回调支持,本 PR 才能完整工作。
参与讨论