分散服务(实验性)
注意
注意: 此功能目前处于实验阶段,相关API在未来的版本中可能会有所更改。
目前TRT-LLM支持disaggregated-service,其中请求的上下文和生成阶段可以在不同的执行器上运行。TRT-LLM的分离服务依赖于执行器API,请确保在阅读文档之前阅读执行器页面。
有关LLM推理中分散服务的更多信息,可以参考诸如DistServe、SplitWise等论文。
用法
enum class RequestType
{
REQUEST_TYPE_CONTEXT_AND_GENERATION = 0,
REQUEST_TYPE_CONTEXT_ONLY = 1,
REQUEST_TYPE_GENERATION_ONLY = 2
};
TRT-LLM 执行器可以执行三种类型的请求:REQUEST_TYPE_CONTEXT_AND_GENERATION、REQUEST_TYPE_CONTEXT_ONLY 和 REQUEST_TYPE_GENERATION_ONLY。执行器执行仅上下文请求的上下文阶段和仅生成请求的生成阶段。当执行器完成仅上下文请求的上下文阶段时,它将维护相应的 kvCache,该缓存将由处理后续仅生成请求的执行器请求。
请注意,环境变量 TRTLLM_USE_MPI_KVCACHE=1 应设置为仅执行上下文请求或仅生成请求。
以下是使用分解服务的一些关键API:
Request request{...};
request.setRequestType(tensorrt_llm::executor::RequestType::REQUEST_TYPE_CONTEXT_ONLY);
auto contextRequestId = contextExecutor.enqueueRequest(request);
auto contextResposnes = contextExecutor.awaitResponses(contextRequestId);
auto contextPhaseParams = contextResposnes.back().getResult().contextPhaseParams.value();
request.setContextPhaseParams(contextPhaseParams);
request.setRequestType(tensorrt_llm::executor::RequestType::REQUEST_TYPE_GENERATION_ONLY);
auto generationRequestId = generationExecutor.enqueueRequest(request);
auto genResposnes = generationExecutor.awaitResponses(generationRequestId);
generationExecutor 将根据附加到请求的 contextPhaseParams 从相应的 contextExecutor 中获取数据,例如 kvCache,因此请确保在获取 generationExecutor 的响应之前,相应的 contextExecutor 没有被关闭。
在上面的代码中,由不同执行器分配给请求的requestId可能不同,用户有责任管理仅用于上下文的请求的requestId与仅用于生成的请求的requestId之间的映射。

在disaggregated-service中需要一个orchestrator来管理多个执行器实例并将请求路由到不同的执行器,TRT-LLM在cpp/include/tensorrt_llm/executor/disaggServerUtil.h中提供了DisaggExecutorOrchestrator类来帮助用户启动多个执行器实例,然而,DisaggExecutorOrchestrator仅以简单的轮询策略将请求路由到执行器,用户需要根据其业务实现自己的orchestrator用于disaggregated-service。
TRT-LLM 目前使用 CUDA-aware MPI 实现 kvCache 传输,所有涉及的执行器进程需要持有相同的 MPI 世界通信器。因此,TRT-LLM 仅支持使用 MPI 启动多个执行器,并且执行器的 CommunicationMode 必须设置为 KLEADER 或 kORCHESTRATOR,并且对于 disaggregated-service,SpawnProcesses=false。TRT-LLM 将在未来的版本中放宽此限制,以便更轻松地管理执行器。
基准测试
请参考 benchmarks/cpp/disaggServerBenchmark.cpp 和 benchmarks/cpp/README.md
故障排除和常见问题解答
常见问题解答
问:TRT-LLM 中分散服务的限制是什么?
A. 目前仅支持decoder-only engine和beamWidth=1,并且模型的每一层的kvCache需要是同质的,具有相同的数据类型和相同数量的注意力头。
问:disaggregated_service 使用的引擎与其他引擎有什么不同吗?
A. 不。引擎构建的参数没有特殊要求。
问:上下文执行器和生成执行器使用的引擎需要相同吗?
A. 不。上下文执行器和生成执行器使用的引擎可以不同,它们的并行性可以是异构的,即TP、PP可以不同,TRT-LLM将处理kvCache的异构性。
问:TRT-LLM 是否支持运行多个上下文执行器实例和生成执行器实例?
A. 是的。TRT-LLM 支持同时运行多个上下文执行器和生成执行器,每个执行器可以使用不同的引擎,但用户有责任将请求路由到不同的执行器并管理 requestId。
问:执行器可以同时运行仅上下文请求和仅生成请求吗?
A. 是的,但不推荐这样做,最好在不同的执行器上运行仅上下文请求和仅生成请求。
问:TRT-LLM中的disaggregated-Service是否支持多GPU和多节点?
A. 是的,建议不同的执行器使用不同的GPU。我们支持仅上下文执行器和仅生成执行器在同一节点或不同节点上运行。每个执行器使用的participantIds和deviceIds需要由用户明确设置,并且每个执行器的participantIds不能相交。
问:TRT-LLM 中对分散服务的要求是什么?
A. TRT-LLM 目前需要 UCX-后端 CUDA-aware-MPI,TRT-LLM 使用 CUDA-aware MPI 实现 kvCache 传输,并将在未来的版本中支持更多的通信组件用于 kvCache 传输。
调试常见问题解答
问:如何处理错误 Disaggregated serving is not enabled, please check the configuration?
A. 请设置环境
export TRTLLM_USE_MPI_KVCACHE=1
问:为什么一些性能分析工具显示,即使在使用NVLink的设备上,TRT-LLM的kvCache传输也没有利用NVLink?
A. 确保使用UCX后端CUDA-aware-MPI运行TRT-LLM,并使用ucx_info -v检查UCX的版本。
如果UCX版本<=1.17,设置UCX_RNDV_FRAG_MEM_TYPE=cuda以启用NVLink。
如果UCX版本=1.18,设置UCX_CUDA_COPY_ASYNC_MEM_TYPE=cuda和UCX_CUDA_COPY_DMABUF=no
问:为什么仅生成请求的token-token延迟不稳定?
A. 当前版本的 TRT-LLM 没有实现仅生成请求的 kvCache 传输和引擎计算之间的重叠,这将在未来的版本中修复。
问:如何处理错误 所有 可用的 序列 槽 已 被使用?
A. 如果 generation_engine 的 pp_size 大于1,可能会出现错误“所有可用的序列槽已被使用”,将在未来的版本中修复。