Skip to content

Bailian gRPC 服务(predict_v2)与 gRPC 配置拆分#813

Closed
xinfei-shi wants to merge 1 commit intomainfrom
develop/bailian
Closed

Bailian gRPC 服务(predict_v2)与 gRPC 配置拆分#813
xinfei-shi wants to merge 1 commit intomainfrom
develop/bailian

Conversation

@xinfei-shi
Copy link
Copy Markdown
Collaborator

@xinfei-shi xinfei-shi commented Mar 22, 2026

Bailian gRPC 服务(predict_v2)

本文档对应变更说明(feat: bailian grpc server)。

摘要

引入 Bailian predict_v2 方向的 Python gRPC 服务端与客户端:补齐 proto、生成脚本与 Bazel 目标,并把 Model RPC(C++)Bailian(Python) 的 gRPC 通道/服务端参数在配置与命令行上拆开,同时在引擎侧统一部分流日志标签,便于排查。

主要变更

1. Bailian gRPC(rtp_llm/bailian/

  • 新增 predict_v2 / model_config 的 proto、proto/BUILD,以及通过 generate_proto_py / create_grpc_proto.py 生成 Python 桩的流程(含 link_py_proto.sh 等辅助脚本)。
  • 实现 gRPC 服务端bailian_grpc_server.py、请求解析 bailian_grpc_request.py、真实/占位响应 bailian_grpc_response_{real,fake}.py、客户端 bailian_grpc_client.pygrpc_client_run.sh
  • 增加 bailian_grpc_request_test 单测与顶层 rtp_llm 打包/BUILD 调整,便于随 wheel/依赖分发。

2. C++ 配置与 Pybind(ConfigModules / ConfigInit

  • 抽取 GrpcMapsConfigclient_config / server_config 映射),GrpcConfig 在其上增加 max_server_pollers(同步服务端 completion queue poller)。
  • 新增 BailianGrpcConfig,包含 Bailian Python 侧 max_server_workersThreadPoolExecutor 规模)及相同的 maps 解析。
  • ConfigInit.cc 等 pybind 中暴露/初始化上述配置,与 Python 侧默认值对齐。

3. 服务端参数与启动链路(grpc_group_args / server_args / frontend_app

  • 将原先混在一起的 gRPC JSON 默认值拆分为:
    • Model RPCinit_model_grpc_group_args--grpc_config_json / GRPC_CONFIG_JSON,默认含 max_server_pollers(常量默认 4)。
    • Bailianinit_bailian_grpc_group_args--bailian_grpc_config_json / BAILIAN_GRPC_CONFIG_JSON,在 Model 默认基础上增加 max_server_workers(默认 4)。
  • 更新 server_args / server_group_args / engine_config / backend_rpc_server_visitor 等,使启动与后端访问使用正确的配置对象。
  • frontend_app.py 增加与 Bailian gRPC 相关的启动/依赖提示(如 proto 生成说明)。

4. 引擎与日志(C++)

  • GenerateStream 等路径补充/统一 streamLogTag() 一类日志标识,并在 BatchDecode / FIFO / Normal / MTP 等调度与流处理处改用该标签,减少仅打 streamId 时的排查成本。

5 破坏性变更:worker_info_port_num 默认值 8 → 9

--worker_info_port_num / WORKER_INFO_PORT_NUM 的默认值由 8 调整为 9server_group_args.pypy_config_modules.MIN_WORKER_INFO_PORT_NUM)。
每台 worker 的端口基址为 start_port + rank_id * worker_info_port_num,其下再挂 RPC、HTTP、Bailian gRPC(base + 8) 等固定偏移。

  • 仅 rank 0:基址仍为 start_port,与旧版一致。
  • 多 rank / 分布式:若此前未显式配置该参数且依赖默认 8,则 rank ≥ 1 的基址会从 start_port + 8k 变为 start_port + 9k各服务端口语会与旧版错位,需更新服务发现、防火墙或运维文档。
  • 若必须维持旧步进,可显式指定 --worker_info_port_num 8(须自行确认是否与 Bailian gRPC 等端口占用冲突)。

6. 其他

  • .gitignorebazel/tf_proto.bzlrtp_llm/server/BUILDRtpLLMOp / RtpEmbeddingOp 等与构建或注册相关的微调。
  • deepep_test.py 等小修复。

配置与迁移说明

场景 参数 说明
Model RPC --grpc_config_json / GRPC_CONFIG_JSON JSON 中 max_server_pollers 控制 C++ 同步服务端 poller(默认由代码注入为 4)。
Bailian --bailian_grpc_config_json / BAILIAN_GRPC_CONFIG_JSON max_server_workers 对应 Python grpc 服务端 ThreadPoolExecutor 规模。

若旧文档或脚本仍只描述「一套 gRPC JSON」,需改为按 Model / Bailian 两套参数分别配置。

测试建议

  • bazel test //rtp_llm/bailian:bailian_grpc_request_test(及本变更涉及的 rtp_llm 相关 target)。
  • 手工或集成:拉起带 Bailian gRPC 的 frontend,验证 predict_v2 流式调用与 Model RPC 互不干扰。

Proto 生成(开发)

在仓库根目录执行:

python -m rtp_llm.bailian.generate_proto_py

需已安装 grpcio-tools。生成物位于 rtp_llm/bailian/proto/

@xinfei-shi xinfei-shi requested a review from LLLLKKKK as a code owner March 22, 2026 14:34
@LLLLKKKK
Copy link
Copy Markdown
Collaborator

🤖 AI Code Review — PR #813 (feat: add bailian predict_v2 gRPC frontend server)

概述

新增 rtp_llm/bailian/ 模块,实现 predict_v2 (Triton-style) gRPC 前端服务器。包含 Python gRPC server(fake/real 模式)、请求解析、响应构建、C++ mock server + UT、Python gRPC client、标准 Triton proto 定义,以及集成到 frontend_app.pybackend_rpc_server_visitor.py 的同步推理路径。

优点

  • 代码结构清晰,模块划分合理(request/response/server/client 分离)
  • 使用标准 Triton predict_v2 proto,兼容性好
  • fake/real 双模式设计便于开发调试
  • C++ mock server 有完整的 UT
  • bazel/tf_proto.bzl 修复了 cc_libs += [...] 在 Starlark select 下的问题

建议改进

P1 - 重要

  1. 生产代码中大量 print() 语句应替换为 logging
    frontend_grpc_response_real.pyfrontend_grpc_response_fake.py 中多处使用 print(f"[server] ...")。生产环境中 print 无法控制日志级别,高 QPS 下会产生大量无用输出。建议改为 logging.debug() 或在合并前删除。

  2. enqueue_sync 每次请求创建新 gRPC channel(model_rpc_client.py
    enqueue_sync 方法每次调用都 grpc.insecure_channel(target_address, ...),高 QPS 下会导致大量 TCP 连接创建/销毁开销。建议复用 channel,类似 async 版本使用 self._channels 缓存。

  3. 缺少 Python 单元测试
    frontend_grpc_request.py(解析逻辑)、frontend_grpc_response_real.pyfrontend_grpc_server.py 没有对应的 Python 单元测试。建议至少为 parse_sampling_paramsparse_input_ids_from_request 添加测试。

P2 - 建议

  1. _run_enqueue_synccollect_enqueue_for_grpc_thread 调用被注释掉
    frontend_grpc_server.py 中已注释掉对 visitor.collect_enqueue_for_grpc_thread 的调用,但 backend_rpc_server_visitor.py 中已实现该方法。如果是调试阶段的临时处理,建议添加 TODO 注释说明计划;否则应启用以获得更好的性能。

  2. request_id hash 截断到 31 位可能导致冲突
    frontend_grpc_response_real.py: req_id = hash(request.id) & 0x7FFFFFFF。在高并发场景下 31 位 hash 冲突概率不低,如果下游用于去重或路由会导致请求混淆。

  3. gRPC ThreadPoolExecutor max_workers=4 硬编码
    建议通过环境变量或参数可配置,4 个 worker 在高并发场景下可能成为瓶颈。

  4. parse_input_ids_and_params 函数未被使用
    frontend_grpc_server.py 分别调用了三个独立的 parse 函数,parse_input_ids_and_params 成了死代码。建议删除或标记。

P3 - Nit

  1. grpc_client_run.shPYTHONCKPT_PATH 默认值包含特定环境路径,建议使用更通用的默认值。

总结

功能完整的新模块,结构清晰。主要建议:清理 print 语句、复用 gRPC channel、补充 Python 单元测试。解决 P1 问题后可以合并。

@LLLLKKKK
Copy link
Copy Markdown
Collaborator

🤖 AI Code Review — PR #813 Develop/bailian (incremental, commit 14691a0)

概述

增量 review(969520b6 → 14691a0,2 commits "feat, fix bailian")。核心架构未变,上一轮 P1 问题均未修复。新发现一个 P0 破坏性变更。

优点

  • 代码结构清晰,proto 使用标准 Triton predict_v2 定义
  • 请求解析和响应构建拆分为独立模块,职责分明
  • C++ mock server 有对应 UT
  • Bazel build 规则和独立 wheel 构建完整

建议改进

P0 - 破坏性变更

  1. worker_info_port_num 默认值从 8 改为 9
    py_config_modules.pyserver_group_args.py 中默认值变更,改变了所有 worker 的端口布局。现有部署如果依赖默认值(未显式设置 --worker_info_port_num),升级后端口分配会错位,导致 worker 间通信失败。需要在 PR description / release notes 中明确标注,并考虑向后兼容。

P1 - 重要(上一轮遗留,仍未修复)

  1. 生产代码中大量 print() 语句bailian_grpc_response_real.pybailian_grpc_response_fake.py 中应改为 logging.debug() 或删除。

  2. enqueue_sync 每次请求创建新 gRPC channelmodel_rpc_client.pyenqueue_sync 应复用 channel,避免高 QPS 下大量 TCP 连接创建/销毁。

  3. 缺少 Python 单元测试parse_sampling_paramsparse_input_ids_from_request 等核心解析逻辑无测试覆盖。

  4. _run_enqueue_sync 未调用已实现的 collect_enqueue_for_grpc_thread — 所有请求走 asyncio.run_coroutine_threadsafe 路径。如果是有意为之应添加 TODO 注释说明计划。

P1 - 新发现

  1. Bailian gRPC server 无条件启动,无 feature flagfrontend_app.py 中每次部署都会占用额外端口(base+8)。应添加环境变量或参数控制是否启用。

P2 - 建议

  1. collect_enqueue_for_grpc_threadasyncio.run() 可能冲突 — gRPC worker 线程可能已有 event loop,asyncio.run() 会抛 RuntimeError。建议统一使用 run_coroutine_threadsafe + fallback。

  2. request_id hash 截断到 31 位 — 高并发场景下冲突概率不低,建议使用更大 hash 空间。

  3. gRPC ThreadPoolExecutor max_workers=4 硬编码 — 建议通过参数可配置。

  4. parse_input_ids_and_params 是死代码 — 未被调用,建议删除。

总结

上一轮 4 个 P1 问题均未修复。新增 P0:worker_info_port_num 默认值变更是影响所有现有部署的破坏性变更。建议在合并前至少解决 P0 和 P1 问题。

@LLLLKKKK
Copy link
Copy Markdown
Collaborator

🤖 AI Code Review — PR #813 — Develop/bailian (v3 incremental, commit 1e0f11f)

概述

PR #813 新增 rtp_llm/bailian/ 模块,实现 predict_v2 (Triton-style) gRPC 前端服务器,包含 Python gRPC server/client、C++ mock server + UT、proto 定义、集成到 frontend_app.py、独立 wheel 构建。本轮增量变更较小,核心架构未变。新发现一个调试残留 P0 问题。

优点

  • 模块结构清晰,proto/server/client/request/response 分层合理
  • C++ mock server 有对应 UT
  • _run_enqueue_sync 有多级 fallback(collect_enqueue_for_grpc_thread → uvicorn loop → dedicated loop)
  • 独立 wheel 构建方便单独部署

建议改进

P0 - 阻塞

  1. maga_server_manager.py 调试残留硬编码路径rtp_llm/test/utils/maga_server_manager.py 第 128 行将 bazel_outputs_dir 覆盖为 /home/xinfei.sxf/work/test,影响所有使用 MagaServerManager 的测试。CI 环境中该路径不存在,会导致测试失败或日志丢失。必须删除此行。

  2. worker_info_port_num 默认值 8→9 是破坏性变更py_config_modules.pyserver_group_args.py 同时修改。现有部署依赖默认值时,升级后端口布局错位导致 worker 间通信失败。需要在 PR description / release notes 中明确标注,或提供向后兼容处理。

P1 - 重要

  1. Bailian gRPC server 无条件启动,无 feature flagfrontend_app.py_start_bailian_grpc_server()start() 中无条件调用,每次部署都占用额外端口(base+8)。建议添加 --enable_bailian_grpc 参数控制。

  2. enqueue_sync 每次请求创建新 gRPC channelmodel_rpc_client.pyenqueue_sync 每次调用都创建 grpc.insecure_channel,高 QPS 下 TCP 连接创建/销毁开销大。应复用 channel(类似 async 版本的 self._channels)。

  3. 缺少 Python 单元测试bailian_grpc_request.pybailian_grpc_response_real.pybailian_grpc_server.py 没有 Python 单元测试。至少应为 parse_sampling_paramsparse_input_ids_from_request 添加测试。

P2 - 建议

  1. collect_enqueue_for_grpc_threadasyncio.run() 可能冲突 — 如果当前线程已有 event loop,asyncio.run() 会抛 RuntimeError。建议统一使用 asyncio.run_coroutine_threadsafe + fallback asyncio.new_event_loop().run_until_complete()

  2. request_id hash 截断至 31 位hash(request.id) & 0x7FFFFFFF 在高并发场景下冲突概率不低,可能导致请求混淆。

  3. gRPC ThreadPoolExecutor max_workers=4 硬编码 — 高并发场景下可能成为瓶颈,建议通过参数可配置。

  4. per-request logging 打印 generated_ids 全量内容bailian_grpc_response_real.pylogging.info("[BailianGrpc] generated_ids: %s", generated_ids) 在高 QPS 下日志量大,建议降级为 debug 或截断。

总结

新发现 P0 调试残留(硬编码个人路径覆盖测试输出目录),加上上一轮遗留的端口默认值破坏性变更,建议在合并前至少解决这两个 P0 和 P1 问题。

@LLLLKKKK
Copy link
Copy Markdown
Collaborator

🤖 AI Code Review — PR #813 Develop/bailian (v4, commit 0f412ff)

概述

新增 rtp_llm/bailian/ 模块,实现 predict_v2 (Triton-style) gRPC 前端服务器。本轮增量引入了多处 C++ 编译错误级别的问题,加上上一轮遗留问题,目前共有 5 个 P0 阻塞项。

优点

  • Bailian gRPC 模块整体架构清晰,proto 定义、client/server、fake/real 模式分离合理
  • C++ mock server + UT 覆盖了基本的 request/response 流程
  • GrpcMapsConfig 基类重构减少了 GrpcConfig / BailianGrpcConfig 之间的代码重复
  • BailianGrpcConfig 的 pickle 兼容性处理(t.size() != 2 && t.size() != 3)正确

建议改进

P0 - 编译错误 / 阻塞

  1. PrefillGenerateContext::stopStream() 编译错误
    PrefillGenerateContext.ccstream->cancel() 应为 stream_->cancel()(成员变量名),且 stream->wait finished() 不是合法 C++ 语法。这段代码替换了原来的 cancel + busy-wait 逻辑,但无法通过编译。

  2. GenerateStream::waitForRemoteGenerate() 拼写错误
    GenerateStream.ccrmote_running() 应为 remote_running(),会导致编译失败。

  3. PrefillRpcServer::remoteLoadCacheEnd() 注释掉关键逻辑无替代
    setRemoteGenerate()releaseResource() 被注释掉但没有替代实现,PD 分离场景下 stream 不会切换到远程 generate 状态。

  4. maga_server_manager.py 硬编码个人调试路径(上轮遗留)
    第 128 行 bazel_outputs_dir = "/home/xinfei.sxf/work/test" 覆盖环境变量读取,影响所有测试。必须删除。

  5. worker_info_port_num 默认值 8→9 破坏性变更(上轮遗留)
    改变所有 worker 端口布局,需在 PR description / release notes 中明确标注。

P1 - 重要

  1. Bailian gRPC server 无条件启动,无 feature flag — 每次部署占用额外端口(base+8),应添加 --enable_bailian_grpc 参数控制。

  2. 缺少 Python 单元测试bailian_grpc_request.pybailian_grpc_response_real.py 等核心模块无测试覆盖。

P2 - 建议

  1. per-request logging 打印全量 generated_ids — 高 QPS 下日志量巨大,建议改为 logging.debug 或仅打印长度。

  2. request_id hash 截断为 31 位 — 高并发场景下冲突概率不低。

总结

本轮新增 3 个 C++ 编译/逻辑错误(P0),加上上轮遗留 2 个 P0,共 5 个 P0 阻塞合并。C++ 编译错误表明变更未经本地编译验证。NOT LGTM — 建议修复所有 P0 后再请求 review。

@LLLLKKKK
Copy link
Copy Markdown
Collaborator

🤖 AI Code Review — PR #813 Develop/bailian (v5, commit 45e4133)

概述

新增 rtp_llm/bailian/ 模块,实现 predict_v2 (Triton-style) gRPC 前端。包含 Python gRPC server/client、C++ mock server + UT、proto 定义、集成到 frontend_app.py、独立 wheel 构建,以及 GrpcMapsConfig 基类重构、max_server_pollers 支持、BailianGrpcConfig C++ struct + pybind。

与 v4 对比

v4 发现的 3 个 C++ 编译错误(PrefillGenerateContext.cc 语法错误、GenerateStream.cc 拼写错误、PrefillRpcServer.cc 注释掉关键逻辑)已修复。这三个文件的 diff 现在仅剩尾部换行符变更。

优点

  • GrpcMapsConfig 基类抽取合理,GrpcConfig / BailianGrpcConfig 共享 client/server map 解析逻辑
  • C++ mock server + UT 覆盖了 proto 层的基本 round-trip
  • from_json 支持 max_workers / max_server_workers 两种 key,向后兼容

建议改进

P0 — 阻塞合并

  1. maga_server_manager.py 硬编码个人调试路径
    第 128 行 bazel_outputs_dir = "/home/xinfei.sxf/work/test" 覆盖了环境变量读取的值,导致 CI 测试日志丢失。必须删除。

  2. worker_info_port_num 默认值 8→9 — 破坏性变更
    py_config_modules.pyserver_group_args.py 同时改动。现有部署依赖默认值时端口会错位。需在 PR description / release notes 中明确标注。

P1 — 重要

  1. Bailian gRPC server 无条件启动,无 feature flagfrontend_app.py_start_bailian_grpc_server() 无条件调用,每次部署占用额外端口(base+8)。建议添加 --enable_bailian_grpc 开关。

  2. 缺少 Python 单元测试bailian_grpc_request.pybailian_grpc_response_real.pybailian_grpc_server.py 无测试。至少应为 parse_sampling_paramsparse_input_ids_from_request 添加测试。

P2 — 建议

  1. per-request logging 打印全量 generated_ids — 高 QPS 下日志量巨大,建议改为 logging.debug 或仅打印长度。

  2. request_id hash 截断为 31 位hash(request.id) & 0x7FFFFFFF 在高并发下冲突概率不低。

总结

相比 v4 修复了 3 个 C++ 编译错误,进展明显。仍有 2 个 P0 未修复(调试路径硬编码 + 端口默认值破坏性变更)。建议修复后再合并。

Verdict: NOT LGTM — 2 个 P0 阻塞合并

@LLLLKKKK
Copy link
Copy Markdown
Collaborator

🤖 AI Code Review — PR #813 (Develop/bailian) v6

Reviewed commit: b360fc8cc7f1 (incremental from 45e41333f3d0)
Verdict: NOT LGTM — 2 个 P0 阻塞合并


遗留 P0(仍未修复,已连续 3 轮提出)

  1. maga_server_manager.py 硬编码个人调试路径 [P0]
    rtp_llm/test/utils/maga_server_manager.py 第 128 行:

    bazel_outputs_dir = "/home/xinfei.sxf/work/test"

    覆盖了上一行从环境变量读取的值,导致所有使用 MagaServerManager.start_server() 的测试在 CI 中失败或日志丢失。必须删除此行。

  2. worker_info_port_num 默认值 8→9 — 破坏性变更 [P0]
    py_config_modules.py: MIN_WORKER_INFO_PORT_NUM = 8 -> 9
    server_group_args.py: --worker_info_port_num default 8 -> 9
    改变了所有 worker 的端口布局。现有部署如果依赖默认值,升级后端口分配会错位。需要在 PR description / release notes 中明确标注,并确认下游消费者已适配。

持续存在的问题

  1. Bailian gRPC server 无条件启动,无 feature flag [P1] — frontend_app.py_start_bailian_grpc_server() 无条件调用,每次部署占用额外端口(base+8)。建议添加 --enable_bailian_grpc 开关。

  2. 缺少 Python 单元测试 [P1] — bailian_grpc_request.pybailian_grpc_response_real.pybailian_grpc_server.py 无 Python UT。

  3. per-request logging 打印全量 generated_ids [P2] — 高 QPS 下日志量巨大,建议改为 logging.debug

  4. request_id hash 截断 31 位 [P2] — 高并发冲突概率不低,建议扩大空间。

  5. grpc_client_run.sh 硬编码个人路径 [P3]

整体评价

v6 与 v5 相比无实质性代码变更。2 个 P0 已连续 3 轮未修复,建议优先处理后再合并。

@xinfei-shi xinfei-shi changed the title Develop/bailian Bailian gRPC 服务(predict_v2)与 gRPC 配置拆分 Mar 25, 2026
@LLLLKKKK
Copy link
Copy Markdown
Collaborator

🤖 AI Code Review — PR #813 Develop/bailian (v7, incremental from b360fc8)

概述

v7 对整个 PR 做了 squash rebase(单 commit feat: bailian grpc server)。v6 的 P0 #1(调试路径硬编码)已修复——maga_server_manager.py 已从 PR 中移除。日志级别和 request_id hash 冲突问题也已修复。新增 streamLogTag() 改善日志关联性,GrpcMapsConfig 基类重构减少代码重复。

优点

  • GrpcMapsConfig 基类重构合理,GrpcConfigBailianGrpcConfig 继承共享 maps
  • streamLogTag() 统一日志格式为 request_id=<id> trace_id=<trace>,全量替换 ~30 处调用
  • _derive_rtp_llm_request_id 使用 SHA256 替代 hash(),避免跨进程 salt 不一致
  • GrpcConfig pickle __setstate__ 正确处理 tuple size 2/3 兼容
  • 新增 bailian_grpc_request_test.py(170 行),覆盖请求解析主要路径

建议改进

P1 - 重要

  1. worker_info_port_num 默认值 8→9 — 破坏性变更需文档标注
    现有部署依赖默认值时,升级后端口分配会错位。请在 PR description 或 release notes 中明确标注。

  2. Bailian gRPC server 无条件启动,无 feature flag
    frontend_app.py_start_bailian_grpc_server() 无条件调用,每次部署占用额外端口 (base+8)。建议添加 --enable_bailian_grpc 参数或环境变量开关。

  3. bailian_grpc_response_real.pybailian_grpc_server.py 缺少单元测试
    请求解析已有测试,但 response 构建和 server 逻辑仍无测试。至少应为 build_stream_response_from_generate_outputs 添加 mock 测试。

P3 - Nit

  1. frontend_app.py 新增 import os 未使用,应删除
  2. 多个 C++ 文件删除了末尾换行符(\ No newline at end of file),建议保留

总结

v7 修复了 v6 的主要阻塞问题。代码质量有明显提升。剩余问题主要是端口变更需文档标注和建议添加 feature flag。

Verdict: Conditional LGTM — P1 需文档标注(端口变更),建议添加 feature flag

@LLLLKKKK
Copy link
Copy Markdown
Collaborator

🤖 AI Code Review — PR #813 Develop/bailian (v8, incremental from 4034325)

概述

本轮增量(3 commits)修复了 v7 提出的 3 个 P1 中的 2 个:补充了 worker_info_port_num 破坏性变更文档(含 breaking-changes.md 和完整使用说明),新增了 323 行 response/server 单元测试。Feature flag 问题降级为 P2。

优点

  • 文档质量优秀docs/backend/Bailian-gRPC.md(124 行)覆盖协议说明、端口计算、启动方式、配置参数、客户端使用、proto 生成和单测命令。docs/release/breaking-changes.md 提供英文 Summary 和迁移方案,便于 release notes 引用。
  • 测试覆盖全面bailian_grpc_response_server_test.py 覆盖 response 构建 6 个场景、request ID 派生、日志标签、iter_real_model_stream_infer 3 个路径(正常/空返回/异常)、BailianGrpcInferenceServicer.ModelStreamInfer 3 个分支(fake/error/real)。
  • C++ 末尾换行符修复:4 个文件恢复 POSIX 规范。
  • 清理 import os:移除 frontend_app.py 中未使用的 import。

v7 问题修复状态

# 问题 级别 状态
1 worker_info_port_num 8→9 需文档标注 P1 ✅ 已修复
2 Bailian gRPC 无条件启动,无 feature flag P1→P2 ⚠️ 未修复,降级 P2
3 response/server 缺少单元测试 P1 ✅ 已修复
4 frontend_app.py 多余 import os P3 ✅ 已修复
5 多个 C++ 文件缺末尾换行符 P3 ✅ 已修复

建议改进

P2 - 建议

  1. Bailian gRPC server 仍无条件启动frontend_app.pystart_bailian_grpc_server_in_thread() 无条件调用,对不需要此功能的用户会占用端口 (base+8) 和线程池。建议后续版本添加 --enable_bailian_grpc 开关。文档已充分说明行为,不阻塞合并。

总结

LGTM — v7 的核心问题(文档缺失、测试缺失)均已修复,代码质量和文档质量都很高。剩余 P2(feature flag)建议后续迭代处理,不阻塞本次合并。

@LLLLKKKK
Copy link
Copy Markdown
Collaborator

🤖 AI Code Review — PR #813 Develop/bailian (v9, commit 406d04b)

概述

本轮增量(1 commit, ~40 行)改进 Bailian gRPC server 启动可靠性:启动同步(调用方阻塞等待 server.start() 完成或超时)、失败处理从 warning 升级为 error + raise、新增 /liveness 健康检查端点。

优点

  • 启动同步设计合理threading.Event + error list 模式简洁正确,success 和 failure 路径都 set() event,不会死锁。Event.wait(timeout) 覆盖了 hang 场景。
  • /liveness 端点:Kubernetes 标准 liveness probe 路径,与 /health 共用 handler,零成本。
  • 死代码清理:移除 _run() 中无用的 global _bailian_grpc_server

建议改进

P1 - 重要

  1. gRPC 启动失败现在是 fatal,但仍无 feature flag 保护
    v8 中 gRPC 启动失败仅 warning 不影响主服务,所以 feature flag 降级为 P2。本轮将 warning 改为 raise,意味着 gRPC 启动失败会导致整个 FastAPI 服务启动失败。结合 gRPC server 仍然无条件启动(无 --enable_bailian_grpc 开关),以下场景会导致服务不可用:

    • 端口 (base+8) 被其他进程占用
    • grpcio / grpcio-tools 未安装
    • 30s 超时(网络/系统负载高时)

    建议:要么 (a) 添加 --enable_bailian_grpc 开关,默认关闭,仅开启时 raise;要么 (b) 保持 warning 降级行为(不 raise),让不需要此功能的用户不受影响。当前状态是最危险的组合——无条件启动 + 失败即 fatal。

P3 - Nit

  1. _bailian_grpc_server 全局变量始终为 None:模块级声明后从未赋值,如果有 graceful shutdown 需求需要在 _run() 成功路径中赋值。

总结

启动同步机制实现正确,但 raise 的引入将 gRPC 启动失败从"可降级"变为"致命错误",在没有 feature flag 的情况下会影响所有不使用 Bailian gRPC 的用户。建议在合并前解决 P1 问题(添加开关或回退 warning 降级)。

Verdict: 需要修改 — 1 个 P1

@LLLLKKKK
Copy link
Copy Markdown
Collaborator

🤖 AI Code Review — PR #813 (Bailian gRPC 服务(predict_v2)与 gRPC 配置拆分)

增量 Review v10 — commit 889c6db (incremental from 406d04b)


增量变更概述

本轮增量新增 bailian_start.sh 部署启动脚本(+96 行),用于百炼平台 HIPPO 容器环境下自动解析模型路径并启动 RTP-LLM 服务。同时将该脚本集成到 Docker 镜像构建流程中。

变更文件(4 files, +105/-1)

文件 改动
open_source/bailian_start.sh 新增 POSIX sh 启动脚本,自动解析 CHECKPOINT_PATH 下最深的模型目录
open_source/package/maga.Dockerfile ADD bailian_start.sh /usr/bin/bailian_start.sh
open_source/package/package_docker.sh 新增 BAILIAN_SH_DIR 变量,内源优先 + 开源 fallback,构建后清理
.gitignore 新增 package/bailian_start.sh

Checklist 检查结果

通用原则

软件工程原则

检查项 结果
SRP bailian_start.sh 职责单一:解析模型路径 + 启动 maga
OCP ✅ 不涉及核心逻辑修改
LSP ✅ 不涉及继承
ISP ✅ 不涉及接口
DIP ✅ 不涉及依赖注入
DRY _bailian_has_model_weights 函数被复用,无重复逻辑
KISS ✅ 脚本逻辑清晰,POSIX sh 兼容性好
YAGNI ✅ 功能与百炼部署需求直接对应

架构审视

检查项 结果
抽象边界 ✅ 启动脚本作为独立入口点,不侵入 Python 代码
依赖方向 ✅ 单向依赖 maga_start.sh,无循环
状态完整性 ✅ 临时文件 mktemp 在使用后 rm -f 清理
错误语义 ✅ 目录不存在、模型未找到、maga_start.sh 缺失均有明确错误信息和非零退出码
可观测性 ✅ 关键变量在启动时 echo 输出
可演进性 CHECKPOINT_PATH 通过环境变量可覆盖
可运维性 ✅ 脚本失败时有清晰错误信息

测试

检查项 结果
新功能有对应测试 ❌ 部署脚本无自动化测试(作为 shell 脚本可接受,建议补充手动测试记录)
删除的测试有等价替代 ✅ 无删除
边界 case 覆盖 ❌ 多候选同深度目录场景未处理(见 P2 #1
分布式改动有多卡测试 ✅ 不涉及

代码质量与文档

检查项 结果
无关改动应分离
mega-PR 应拆分 ❌ 整个 PR 50 files +6469 行(历史问题)
Commit 原子性 ✅ 本轮 commit 自包含
Commit message 准确性 feat, grpc 过于笼统,实际是部署脚本
PR description
日志频率控制

领域检查

  • A. 兼容性与配置 — 全部 ✅
  • B. 正确性与逻辑 — ❌ 见 P2 支持一下OpenAI风格的借口呗 #1(多候选目录不确定性)
  • C. 线程安全与并发 — 全部 ✅(不涉及)
  • D. 性能 — 全部 ✅(不涉及热路径)
  • E. 分布式 — 全部 ✅(不涉及)
  • F. 跨平台 — 全部 ✅(POSIX sh 兼容)
  • G. 语言与框架特有 — 全部 ✅(不涉及 Python/C++)
  • H. 测试与 CI — ❌ 部署脚本无自动化测试
  • I. 代码质量 — 全部 ✅

Review 意见

问题

  1. "最深路径" 策略在多候选场景下不确定 [P2]
    _bailian_resolve_checkpoint 选择 ${#_arc_dir} 最大的目录。当存在多个同长度候选目录时(如 .../ModelA/ModelA.../ModelB/ModelB),结果取决于 find 输出顺序。
    建议:如果百炼平台保证每个容器只有一个模型,在注释中明确说明前提假设;否则发现多个候选时报错退出。

  2. Commit message feat, grpc 不准确 [P3]
    本轮 commit 实际是新增百炼部署启动脚本,与 gRPC 无直接关系。建议改为 feat: add bailian_start.sh deployment script

  3. maga.Dockerfilebailian_start.sh 路径硬编码 [P3]
    maga_start.sh 使用 ARG START_FILE 参数化,但 bailian_start.sh 直接硬编码。建议保持一致或注释说明原因。

历史遗留问题(未在本轮修复)

  1. gRPC 启动失败 fatal + 无 feature flag [P1,v9 遗留]
    frontend_app.py 中 gRPC 无条件启动 + 失败即 raise。建议添加 --enable_bailian_grpc 开关或回退到 warning 降级。

  2. gRPC channel per-request 创建 [P1,v7 遗留]
    bailian_grpc_client.py 中每次请求创建新 channel,高 QPS 下导致 TCP 连接风暴。建议复用 channel pool。

改进亮点

  • POSIX sh 兼容性好,避免 bash 特有语法
  • 错误处理完善:三种失败场景都有清晰 stderr 错误信息和非零退出码
  • 临时文件 mktemp 使用后 rm -f 清理,无泄漏
  • return 1 2>/dev/null || exit 1 模式同时支持 source 和直接执行
  • Docker 构建集成与 maga_start.sh 模式一致(内源优先 + 开源 fallback)

整体评价

本轮增量改动质量良好,bailian_start.sh 实现了百炼平台部署所需的模型路径自动解析,错误处理完善,POSIX 兼容性好。本轮新增问题均为 P2/P3 级别。

但 PR 整体仍有 2 个历史遗留 P1 未解决:(1) gRPC 无条件启动 + 失败 fatal;(2) gRPC channel per-request 创建。建议在合并前解决。

Verdict: 本轮增量 LGTM(无新增 P0/P1),但 PR 整体仍有 2 个历史遗留 P1 待解决

@LLLLKKKK
Copy link
Copy Markdown
Collaborator

🤖 AI Code Review — PR #813

PR 概述

Title: Bailian gRPC 服务(predict_v2)与 gRPC 配置拆分
Author: xinfei-shi
规模: 50(GitHub) + 12(内源) files, ~+3500/-200

核心目标

引入 Bailian predict_v2 方向的 Python gRPC 服务端/客户端,将 Model RPC(C++)与 Bailian(Python)的 gRPC 配置在命令行和代码层面拆分为独立参数,同时统一 C++ 侧流日志标签(streamLogTag())便于排查。


改动逻辑拆解

GitHub 开源仓库变更(主要代码)

1. C++ 配置层(ConfigModules / ConfigInit)

  • 抽取 GrpcMapsConfig 基类(client_config / server_config maps),GrpcConfig 继承并新增 max_server_pollers,新增 BailianGrpcConfig 继承并新增 max_server_workers
  • JSON 解析重构为 parse_grpc_client_server_maps_json + parse_optional_root_int_json 静态函数复用
  • ConfigInit.cc pybind 注册 BailianGrpcConfigGrpcConfig pickle 兼容 2/3 元素 tuple

2. Python 配置与启动链路

  • grpc_group_args.pyinit_grpc_group_args 拆分为 init_model_grpc_group_args + init_bailian_grpc_group_args,各自独立 --grpc_config_json / --bailian_grpc_config_json
  • py_config_modules.pyMIN_WORKER_INFO_PORT_NUM 8→9,ServerConfig 新增 bailian_grpc_server_port(base+8),PyEnvConfigs 新增 bailian_grpc_config
  • engine_config.pyEngineConfig dataclass 新增 bailian_grpc_config 字段
  • server_group_args.pyworker_info_port_num 默认值 8→9

3. Bailian gRPC 服务实现(新增 rtp_llm/bailian/

  • bailian_grpc_server.py:gRPC server 启动(daemon thread + wait_for_termination),fake/real 双模式,_run_enqueue_sync 桥接 async enqueue 到 gRPC worker thread
  • bailian_grpc_request.py:解析 ModelInferRequest 中的 input_ids、sampling 张量、return_input_ids
  • bailian_grpc_response_real.py:从 GenerateOutputs 构建 ModelStreamInferResponse(generated_ids / finish_reason / aux_info metrics)
  • bailian_grpc_response_fake.py:mock 模式(input_ids + 100)
  • bailian_grpc_client.py:客户端,使用 TokenizerFactory 编码 prompt 后发送 ModelStreamInfer
  • proto:predict_v2.proto(NVIDIA Triton 标准)+ model_config.proto,含 Python 桩生成脚本

4. Frontend 集成

  • frontend_app.py_start_bailian_grpc_serverstart() 中准备,_run_bailian_grpc_server_startup 在 FastAPI startup 中执行(lazy import grpcio),新增 /liveness 端点

5. C++ 日志统一(streamLogTag)

  • GenerateStream 新增 streamLogTag() 方法(request_id=<id> trace_id=<trace>
  • GenerateStream.ccFIFOScheduler.ccNormalBatchStreamProcessor.ccBatchDecodeScheduler.hMtpBatchStreamProcessor.cc 等多处 streamId()streamLogTag()

6. 其他

  • .gitignore 新增 proto 生成物和 bailian_start.sh
  • bazel/tf_proto.bzlcc_libs += [...]cc_libs = cc_libs + [...](避免 list mutation)
  • open_source/bailian_start.sh:Bailian 部署启动脚本(HIPPO workdir fix + checkpoint 自动发现)
  • backend_rpc_server_visitor.py:import 合并 + 格式化
  • deepep_test.py:小修复
  • 文档:Bailian-gRPC.mdbreaking-changes.mdserver_arguments.md

内源仓库变更(CI/测试/内部配置)

1. Smoke 测试

  • 新增 bailian_grpc_comparer.py(Bailian gRPC smoke 测试比较器)
  • case_runner.py 新增 Bailian gRPC case 支持
  • 新增 q_r_bailian_grpc.json 测试数据
  • defs.bzl / BUILD 新增 Bailian gRPC smoke 测试目标

2. 打包/镜像

  • Dockerfile 新增 bailian_start.sh COPY
  • image-opensource.yaml:新增 Bailian 相关构建步骤

Checklist 检查结果

通用原则

软件工程原则

检查项 结果
SRP ✅ 各模块职责清晰:request 解析、response 构建、server 启动分离
OCP ✅ fake/real 双模式通过 backend_visitor 参数切换,不修改核心逻辑
LSP GrpcConfig / BailianGrpcConfig 继承 GrpcMapsConfig 契约一致
ISP
DIP run_enqueue_sync 通过参数注入,便于测试 mock
DRY parse_grpc_client_server_maps_json / append_grpc_maps_to_stream 复用
KISS
YAGNI

架构审视

检查项 结果
抽象边界 ✅ Bailian gRPC 作为独立模块,通过 backend_visitor 接入主链路
依赖方向 bailianops/config/utils,无循环依赖
状态完整性 ❌ 见 P2-1:_bailian_grpc_server 全局单例无 shutdown/reset 机制
错误语义 ✅ 启动失败 raise,enqueue 异常返回 error_message
可观测性 ✅ 日志充分,streamLogTag 统一
可演进性 ✅ 配置独立,proto 标准
可运维性 ❌ 见 P1-1:worker_info_port_num 默认值变更是破坏性变更

测试

检查项 结果
新功能有对应测试 bailian_grpc_request_test(170 行)+ bailian_grpc_response_server_test(323 行)+ 内源 smoke 测试
删除的测试有等价替代 ✅ 无删除
边界 case 覆盖 ✅ 空 input_ids、raw mismatch、empty outputs、exception 路径均覆盖
分布式改动有多卡测试 ✅ 端口布局变更不涉及分布式计算逻辑

代码质量与文档

检查项 结果
无关改动分离 ❌ 见 P2-2:backend_rpc_server_visitor.py 纯格式化混入功能 PR
mega-PR 拆分 ❌ 见 P2-3:PR 包含 5 个独立功能方向,建议拆分
Commit 原子性 ✅ 单 commit,虽大但自包含
Commit message 准确性
PR description 说明动机和设计 ✅ 非常详细,含迁移说明和破坏性更文档
日志频率控制 ✅ Bailian gRPC 日志均为 DEBUG 级别

领域检查

A. 兼容性与配置

检查项 结果
环境变量/参数重命名有兼容 fallback(1.1) ❌ 见 P1-1:worker_info_port_num 默认值 8→9 无 deprecation warning
默认值变更已评估影响(1.2) ✅ PR description 详细说明了影响范围和迁移方案
新增配置字段传播至所有变体(1.12) BailianGrpcConfigPyEnvConfigs / EngineConfig / pybind 均传播
可选依赖 lazy import(1.32) grpcio_run_bailian_grpc_server_startup 中 lazy import

B. 正确性与逻辑

检查项 结果
逻辑错误 / off-by-one
边界 case
死代码 / 不可达分支(1.7)
状态标志生命周期(1.16) ❌ 见 P2-1:_bailian_grpc_server 全局变量只 set 不 reset

C. 线程安全与并发

检查项 结果
静态/全局状态 atomic(1.10) ❌ 见 P2-4:_enqueue_loop 全局变量无锁保护
TOCTOU 竞态(1.10) _get_async_loop 有 lock 保护

D. 性能 — 全部 ✅

E. 分布式 — 全部 ✅

F. 跨平台(ROCm/ARM) — 全部 ✅

G. 语言与框架特有

检查项 结果
Python 变量安全(1.8)
Python 重命名全局搜索(1.17) init_grpc_group_argsinit_model_grpc_group_args 已更新所有消费者
gRPC channel 复用(1.40) ✅ 客户端是 CLI 工具,per-run 创建 channel 合理
环境变量滥用(1.36) ✅ 新增参数走 --bailian_grpc_config_json 命令行

H. 测试与 CI — 全部 ✅

I. 代码质量 — 全部 ✅


Review 意见

问题

  1. worker_info_port_num 默认值 8→9 缺少运行时 deprecation warning [P1]
    虽然 PR description 和文档详细说明了破坏性变更,但代码层面没有任何运行时提示。多 rank 分布式部署如果未显式设置该参数,升级后 rank>=1 的端口会静默偏移,可能导致服务发现失败。
    建议:在 server_group_args.py 解析后或 ServerConfig 初始化时,如果 worker_info_port_num 使用默认值且 tp_size > 1rank_id > 0,打印一条 WARNING 日志提示默认值已变更。或者在启动日志中始终打印当前 worker_info_port_num 值和端口布局。
    位置:rtp_llm/server/server_args/server_group_args.pyrtp_llm/config/py_config_modules.py

  2. _bailian_grpc_server 全局单例无 shutdown/reset 机制 [P2]
    bailian_grpc_server.py_bailian_grpc_server 全局变量只在 start_bailian_grpc_server 中赋值,没有 stop_bailian_grpc_server 或 reset 路径。虽然当前场景下进程退出即清理,但如果未来需要 graceful shutdown(如 shutdown_timeout 场景),缺少 server.stop(grace) 调用。
    建议:添加 stop_bailian_grpc_server(grace=None) 函数,在 frontend_app shutdown 时调用。
    位置:rtp_llm/bailian/bailian_grpc_server.py:151-187

  3. backend_rpc_server_visitor.py 纯格式化混入功能 PR [P2]
    该文件的改动全部是空白行调整和 import 合并,与 Bailian gRPC 功能无关。按 review patterns 1.4,格式化改动应与功能改动分离。
    建议:后续 PR 中分离纯格式化改动。

  4. PR 包含多个独立功能方向 [P2]
    本 PR 同时包含:(1) Bailian gRPC 服务实现 (2) gRPC 配置拆分 (3) worker_info_port_num 默认值变更 (4) C++ streamLogTag() 日志统一 (5) /liveness 端点。其中 (3)(4)(5) 可独立 PR。
    建议:当前 PR 已较成熟,不强制要求拆分,但后续类似规模的改动建议拆分。

  5. _enqueue_loop 全局变量无锁保护 [P2]
    set_bailian_grpc_enqueue_event_loop 写入 _enqueue_loop_run_enqueue_sync 读取它,两者在不同线程执行。Python GIL 在 CPython 下保证了引用赋值的原子性,实际不会出问题,但从代码规范角度,建议使用 threading.Lock 或至少添加注释说明依赖 GIL 保证。
    位置:rtp_llm/bailian/bailian_grpc_server.py:53-68

  6. parse_optional_root_int_json 正则不支持负数 [P3]
    ConfigModules.ccparse_optional_root_int_json 的正则 (\\d+) 只匹配正整数。虽然当前 max_server_pollersmax_server_workers 不会为负,但作为通用解析函数,建议改为 (-?\\d+)
    位置:rtp_llm/cpp/config/ConfigModules.cc:401-409

  7. _run_enqueue_sync 无超时保护 [P3]
    asyncio.run_coroutine_threadsafe(collect(), loop).result() 无 timeout 参数,如果 backend enqueue hang,gRPC worker thread 会永久阻塞。
    建议:添加合理的 timeout(如 max_rpc_timeout_ms 对齐),超时后返回 error_message。
    位置:rtp_llm/bailian/bailian_grpc_server.py:113

小问题

  • bailian_grpc_client.py:297 默认 --grpc_addr127.0.0.1:8608,但按默认端口布局 rank0 的 Bailian gRPC 端口应为 8088+8=8096,建议修正默认值或在 help 中说明。
  • bailian_start.sh 使用 find 递归搜索 config.json,在大目录树下可能较慢,建议限制 maxdepth

整体评价

PR 整体质量较高,架构设计清晰(fake/real 双模式、配置拆分、lazy import),文档和测试覆盖充分。破坏性变更(worker_info_port_num 8→9)在 PR description 中有详细说明和迁移指南,但缺少运行时 warning 是主要风险点。C++ 侧 streamLogTag() 统一是有价值的改进。

存在阻塞/重要问题(P1-1:worker_info_port_num 默认值变更缺少运行时 deprecation warning,多 rank 部署可能静默故障)

@LLLLKKKK LLLLKKKK closed this Mar 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants