-
Notifications
You must be signed in to change notification settings - Fork 2.7k
[#17016][feat] Add selectable OpenEngine gRPC server #17084
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
yuanjingx87
merged 15 commits into
NVIDIA:main
from
connorcarpenter15:feat/openengine-server-stub
Aug 28, 2026
Merged
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
0e8c677
feat(openengine): add stub gRPC protocol
connorcarpenter15 ba31a73
fix(grpc): address protocol launch feedback
connorcarpenter15 c8731fc
fix(grpc): harden server startup and shutdown
connorcarpenter15 3e01ca0
fix(grpc): preserve rebased CLI metadata
connorcarpenter15 2f20313
fix(cli): align gRPC protocol stability metadata
connorcarpenter15 0258d6a
ci: update Docker images for OpenEngine
connorcarpenter15 8476d0b
ci: refresh OpenEngine Docker images
connorcarpenter15 6b8daf2
ci: skip empty test selections
connorcarpenter15 8e9b081
Revert "ci: skip empty test selections"
connorcarpenter15 30993b6
fix(ci): detect Linux distribution without distro
connorcarpenter15 15efc5f
revert(ci): restore distro-based Linux detection
connorcarpenter15 8e768df
[None][fix] Pin distro for CI sysinfo detection (#18004)
chzblych 6113b4b
chore: merge upstream main
connorcarpenter15 5c122f6
chore: merge upstream main
connorcarpenter15 0db4eef
ci: refresh OpenEngine Docker images
connorcarpenter15 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| # Source: https://github.com/ai-dynamo/openengine/releases/tag/v0.1.0 | ||
| # BSR module: https://buf.build/openengine/openengine | ||
| # Immutable BSR commit: 768a93c7b44e40f28c692ad0b471a8f2 | ||
| --extra-index-url https://buf.build/gen/python | ||
| openengine-openengine-grpc-python==1.67.1.2.20260730172104+768a93c7b44e | ||
|
connorcarpenter15 marked this conversation as resolved.
|
||
| openengine-openengine-protocolbuffers-python==31.1.0.2.20260730172104+768a93c7b44e | ||
| openengine-openengine-protocolbuffers-pyi==31.1.0.2.20260730172104+768a93c7b44e | ||
|
connorcarpenter15 marked this conversation as resolved.
|
||
| grpcio>=1.67.1,<2 | ||
| protobuf>=6.31.1,<7 | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| <!-- SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. --> | ||
| <!-- SPDX-License-Identifier: Apache-2.0 --> | ||
|
|
||
| # TensorRT-LLM OpenEngine stub server | ||
|
|
||
| `trtllm-serve` can expose an experimental OpenEngine gRPC server instead of its normal OpenAI HTTP server. SMG remains the default gRPC protocol. | ||
|
|
||
| Install the optional Python bindings from the Buf Schema Registry: | ||
|
|
||
| ```bash | ||
| python -m pip install \ | ||
| --extra-index-url https://buf.build/gen/python \ | ||
| "tensorrt_llm[openengine]" | ||
| ``` | ||
|
|
||
| Then select OpenEngine when starting the gRPC server: | ||
|
|
||
| ```bash | ||
| trtllm-serve <model> \ | ||
| --grpc \ | ||
| --grpc-protocol openengine \ | ||
| --host 0.0.0.0 \ | ||
| --port 50051 | ||
| ``` | ||
|
|
||
| Existing `--grpc` invocations continue to select SMG. OpenEngine and VisualGen cannot be enabled together. | ||
|
|
||
| This initial integration is a protocol stub. Every OpenEngine RPC returns gRPC status `UNIMPLEMENTED`; no request reaches the TensorRT-LLM engine. OpenEngine and SMG are independent protocol integrations. This integration does not make a replacement or convergence decision between them. | ||
|
|
||
| ## Dependency provenance | ||
|
|
||
| The schema source is the Apache-2.0-licensed [`ai-dynamo/openengine`](https://github.com/ai-dynamo/openengine) repository at signed Git tag [`v0.1.0`](https://github.com/ai-dynamo/openengine/releases/tag/v0.1.0). That release maps to the public [`buf.build/openengine/openengine`](https://buf.build/openengine/openengine) module at immutable BSR commit `768a93c7b44e40f28c692ad0b471a8f2`. | ||
|
|
||
| The BSR generated the pinned wheels from that module commit: | ||
|
|
||
| | Package | Generator | Version | SHA-256 | | ||
| | --- | --- | --- | --- | | ||
| | `openengine-openengine-grpc-python` | [`grpc/python`](https://buf.build/grpc/python) | `1.67.1.2.20260730172104+768a93c7b44e` | `1485aed9799c4eb9367d1a261ca5cc5319f1e9b8d950ac98a26f3cb3641b8cf6` | | ||
| | `openengine-openengine-protocolbuffers-python` | [`protocolbuffers/python`](https://buf.build/protocolbuffers/python) | `31.1.0.2.20260730172104+768a93c7b44e` | `6eae12c3d8d06147fccf608da9772d6391139031fabdafdb7cf4c71a19c1f25e` | | ||
| | `openengine-openengine-protocolbuffers-pyi` | [`protocolbuffers/pyi`](https://buf.build/protocolbuffers/pyi) | `31.1.0.2.20260730172104+768a93c7b44e` | `8b0a054dbdaaa67459b3fa4786f13d8f6f4d30cf30be325f5416dbd97aba46a6` | | ||
|
|
||
| Buf documents the package naming and version format in its [Python-generated SDK guide](https://buf.build/docs/bsr/generated-sdks/python/). The final version segment is the BSR commit prefix. The exact requirements are pinned in `requirements-openengine.txt`. | ||
|
|
||
| ## Maintenance boundary | ||
|
|
||
| The OpenEngine contributor community owns this adapter, its tests, protocol version updates, and integration bugs. TensorRT-LLM internal APIs do not provide compatibility guarantees to protocol adapters. Adapter updates must follow core runtime changes and must not block normal TensorRT-LLM development or releases. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| """OpenEngine gRPC integration for TensorRT-LLM.""" | ||
|
|
||
| from .server import OpenEngineServer, launch_server | ||
|
|
||
| __all__ = ["OpenEngineServer", "launch_server"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,100 @@ | ||
| # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| """OpenEngine gRPC server lifecycle for TensorRT-LLM.""" | ||
|
|
||
| import asyncio | ||
| import signal | ||
|
|
||
| import grpc | ||
| import uvloop | ||
| from openengine.v1 import openengine_pb2_grpc | ||
|
|
||
| from tensorrt_llm.logger import logger | ||
|
|
||
| __all__ = ["OpenEngineServer", "launch_server"] | ||
|
|
||
|
|
||
| def _format_bind_address(host: str, port: int) -> str: | ||
| """Format a host and port as a gRPC bind address.""" | ||
| if ":" in host and not (host.startswith("[") and host.endswith("]")): | ||
| host = f"[{host}]" | ||
| return f"{host}:{port}" | ||
|
|
||
|
|
||
| class OpenEngineServer: | ||
| """OpenEngine gRPC server with intentionally unimplemented RPCs. | ||
|
|
||
| Args: | ||
| host: Interface on which the server listens. | ||
| port: Port on which the server listens. Use zero to select a free port. | ||
| """ | ||
|
|
||
| def __init__(self, host: str, port: int) -> None: | ||
| self.host = host | ||
| self.port = port | ||
| self._server = grpc.aio.server() | ||
| openengine_pb2_grpc.add_InferenceServicer_to_server( | ||
| openengine_pb2_grpc.InferenceServicer(), self._server | ||
| ) | ||
| openengine_pb2_grpc.add_ControlServicer_to_server( | ||
| openengine_pb2_grpc.ControlServicer(), self._server | ||
| ) | ||
| self._bind_address = _format_bind_address(host, port) | ||
| bound_port = self._server.add_insecure_port(self._bind_address) | ||
| if bound_port == 0: | ||
| raise RuntimeError(f"Failed to bind OpenEngine server to {self._bind_address}") | ||
| if port == 0: | ||
| self.port = bound_port | ||
|
|
||
| async def start(self) -> None: | ||
| """Start accepting OpenEngine requests.""" | ||
| await self._server.start() | ||
| address = _format_bind_address(self.host, self.port) | ||
| logger.info(f"OpenEngine stub server started on {address}") | ||
|
|
||
| async def stop(self, grace: float = 5.0) -> None: | ||
| """Stop accepting OpenEngine requests. | ||
|
|
||
| Args: | ||
| grace: Maximum time in seconds to allow active RPCs to finish. | ||
| """ | ||
| await self._server.stop(grace=grace) | ||
| logger.info("OpenEngine stub server stopped") | ||
|
|
||
|
connorcarpenter15 marked this conversation as resolved.
|
||
| async def wait_for_termination(self) -> None: | ||
| """Wait until the OpenEngine server terminates.""" | ||
| await self._server.wait_for_termination() | ||
|
|
||
|
|
||
| def launch_server(host: str, port: int) -> None: | ||
| """Launch the dedicated OpenEngine gRPC server. | ||
|
|
||
| Args: | ||
| host: Interface on which the server listens. | ||
|
brnguyen2 marked this conversation as resolved.
|
||
| port: Port on which the server listens. | ||
| """ | ||
|
|
||
| async def serve() -> None: | ||
| server = OpenEngineServer(host=host, port=port) | ||
| loop = asyncio.get_running_loop() | ||
| stop_event = asyncio.Event() | ||
|
|
||
| def signal_handler() -> None: | ||
| logger.info("Received shutdown signal") | ||
| stop_event.set() | ||
|
|
||
| for sig in (signal.SIGTERM, signal.SIGINT): | ||
| loop.add_signal_handler(sig, signal_handler) | ||
|
|
||
| try: | ||
| logger.warning( | ||
| "OpenEngine protocol support is a stub: no model is loaded and " | ||
| "all RPCs return UNIMPLEMENTED." | ||
| ) | ||
| await server.start() | ||
| await stop_event.wait() | ||
| finally: | ||
| await server.stop() | ||
|
|
||
|
brnguyen2 marked this conversation as resolved.
|
||
| uvloop.run(serve()) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.