Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@ SPDX-License-Identifier: Apache-2.0
## Overview

OpenEngine defines a runtime boundary around an inference engine. An engine
exposes the `openengine.v1.OpenEngine` gRPC service, which applications can call
directly or distributed frameworks can use to coordinate engine workers.
exposes the `openengine.v1.Inference` and `openengine.v1.Control` services.
Applications can call the inference service directly, while distributed
frameworks use both services to coordinate engine workers.

Both paths use generated clients and the same typed contract without sharing a
process, Python environment, dependency tree, or private control API.
Expand All @@ -67,7 +68,7 @@ scheduler implementation details.

| Without a shared contract | With OpenEngine |
| --------------------------------------------------- | --------------------------------------------------- |
| Engine-specific clients and framework integrations | One generated service contract |
| Engine-specific clients and framework integrations | One generated protocol contract |
| Configuration duplicated into sidecars | Engine capabilities discovered over RPC |
| Engine upgrades coupled to framework code | Engine-native execution behind a common endpoint |
| Ad hoc cancellation and failure behavior | Explicit lifecycle and terminal error semantics |
Expand Down Expand Up @@ -108,9 +109,9 @@ The canonical schema is organized by domain under
| Non-generative tasks | Typed embedding, classification, and grouped query/candidate scoring with stable correlation |
| Structured output | JSON Schema, JSON object, regex, EBNF grammar, structural tags, and fixed choices |
| Token information | Prompt and output logprobs, ranks, candidate-token selection, per-token records, and streamed text deltas |
| Discovery | Engine identity, schema revision, role, model limits, topology, parser configuration, and generation capabilities |
| Discovery | Server identity, schema revision, role, model limits, topology, parser configuration, and generation capabilities |
| Lifecycle | Health checks, targeted or global abort, graceful drain, progress, and terminal failures |
| Disaggregated serving | Prefill/decode roles, KV session handoff, connector discovery, rank affinity, and cache controls |
| Disaggregated serving | Prefill/decode roles, decode-context parallel topology, KV handoff, connector discovery, and cache controls |
| KV-aware routing | Typed KV event streams plus discovery of engine-native event sources |
| Model extensions | Multimodal inputs and LoRA adapter lifecycle |
| Observability | Point-in-time load snapshots and structured runtime event streams |
Expand Down
31 changes: 23 additions & 8 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,19 @@ package openengine.v1;

import "google/protobuf/struct.proto";

service OpenEngine {
service Inference {
// Core inference path.
rpc Generate(GenerateRequest) returns (stream GenerateResponse);

// Non-generative inference paths.
rpc Embed(EmbedRequest) returns (EmbedResponse);
rpc Classify(ClassifyRequest) returns (ClassifyResponse);
rpc Score(ScoreRequest) returns (ScoreResponse);
}

service Control {
// Runtime metadata and scheduling state.
rpc GetEngineInfo(GetEngineInfoRequest) returns (EngineInfo);
rpc GetServerInfo(GetServerInfoRequest) returns (ServerInfo);
rpc GetModelInfo(GetModelInfoRequest) returns (ModelInfo);
rpc GetLoad(GetLoadRequest) returns (LoadInfo);

Expand All @@ -54,9 +56,14 @@ service OpenEngine {
}
```

`Inference` is the inference data plane. `Control` is the discovery, lifecycle,
and coordination control plane. Implementations may expose both services on the
same listener, or isolate them on separate listeners and access policies without
changing the protocol contract.

---

## Core identity and roles
## Server identity and engine roles

```protobuf
enum EngineRole {
Expand All @@ -66,12 +73,12 @@ enum EngineRole {
ENGINE_ROLE_DECODE = 3;
}

message GetEngineInfoRequest {}
message GetServerInfoRequest {}

message EngineInfo {
message ServerInfo {
string engine_name = 1; // sglang, vllm, tensorrt_llm, etc.
string engine_version = 2;
EngineRole role = 3;
EngineRole engine_role = 3;
string instance_id = 4;
repeated string supported_models = 5;
ParallelismInfo parallelism = 6;
Expand All @@ -87,6 +94,8 @@ message ParallelismInfo {
optional uint32 data_parallel_size = 3;
optional uint32 data_parallel_rank = 4;
optional uint32 data_parallel_start_rank = 5;
// Number of ranks in each decode-context-parallel group. Must be at least 1.
optional uint32 decode_context_parallel_size = 6;
}
```

Expand All @@ -111,6 +120,12 @@ Discovery response scalars use proto3 `optional` presence. An absent value means
the engine cannot report the value; an explicitly present zero or `false` is a
reported value and must not be replaced with a client default.

`decode_context_parallel_size` reports the number of ranks across which decode
context is sharded. It describes a group within the server's execution topology
and does not, by itself, imply additional workers beyond the reported tensor,
pipeline, and data-parallel topology. When present, the value must be at least
one; one means decode-context parallelism is disabled.

Role semantics:

- `AGGREGATED`: accepts normal generation requests and returns tokens.
Expand Down Expand Up @@ -192,15 +207,15 @@ enum GuidedDecodingMode {
```

`GetModelInfoRequest.model` is required and selects one of
`EngineInfo.supported_models`; an unknown model returns gRPC `NOT_FOUND`.
`ServerInfo.supported_models`; an unknown model returns gRPC `NOT_FOUND`.
Capability submessages distinguish unreported support (message absent) from
reported support or lack of support (`supported = true` or `false`). Candidate
selection modes and `max_top_n` are reported independently for prompt and
output logprobs. The remaining generation fields advertise support and limits
for the corresponding request options.

`supports_lora=true` means the engine accepts `GenerateRequest.lora_name` and
the LoRA lifecycle RPCs on `OpenEngine`.
the LoRA lifecycle RPCs on `Control`.

---

Expand Down
4 changes: 2 additions & 2 deletions docs/motivation.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ request and control data needed across the process boundary.
| Area | Contract |
| --- | --- |
| Generation | Streaming tokens, usage, finish state, and errors |
| Discovery | Engine, model, role, topology, limits, and capabilities |
| Discovery | Server, model, engine role, topology, limits, and capabilities |
| Lifecycle | Health, abort, and drain |
| Scheduling | Load data and data-parallel rank affinity |
| Scheduling | Load data, data-parallel rank affinity, and decode-context parallel topology |
| Disaggregation | Prefill readiness, KV-session handoff, and connector data |
| KV routing | Event streams and native event-source discovery |

Expand Down
4 changes: 2 additions & 2 deletions proto/openengine/v1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ share the same package and together define the API.

| File | Area |
| --- | --- |
| [`openengine.proto`](openengine.proto) | `OpenEngine` service and RPC declarations |
| [`openengine.proto`](openengine.proto) | `Inference` and `Control` service declarations |
| [`input.proto`](input.proto) | Shared text, token, and multimodal inputs |
| [`engine.proto`](engine.proto) | Engine identity, roles, and parallelism |
| [`server.proto`](server.proto) | Server identity, engine roles, and parallelism |
| [`model.proto`](model.proto) | Model metadata and inference capabilities |
| [`generation.proto`](generation.proto) | Generation requests, parameters, streamed events, and usage |
| [`tasks.proto`](tasks.proto) | Shared non-generative task request and output vocabulary |
Expand Down
2 changes: 1 addition & 1 deletion proto/openengine/v1/lifecycle.proto
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ syntax = "proto3";

package openengine.v1;

import "openengine/v1/engine.proto";
import "openengine/v1/error.proto";
import "openengine/v1/kv.proto";
import "openengine/v1/server.proto";

message HealthRequest {
// False means a lightweight readiness/liveness check. True asks the engine to
Expand Down
8 changes: 5 additions & 3 deletions proto/openengine/v1/openengine.proto
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,28 @@ package openengine.v1;

import "openengine/v1/classification.proto";
import "openengine/v1/embedding.proto";
import "openengine/v1/engine.proto";
import "openengine/v1/generation.proto";
import "openengine/v1/kv.proto";
import "openengine/v1/lifecycle.proto";
import "openengine/v1/lora.proto";
import "openengine/v1/model.proto";
import "openengine/v1/observability.proto";
import "openengine/v1/scoring.proto";
import "openengine/v1/server.proto";

service OpenEngine {
service Inference {
// Core inference path.
rpc Generate(GenerateRequest) returns (stream GenerateResponse);

// Non-generative inference paths.
rpc Embed(EmbedRequest) returns (EmbedResponse);
rpc Classify(ClassifyRequest) returns (ClassifyResponse);
rpc Score(ScoreRequest) returns (ScoreResponse);
}

service Control {
// Runtime metadata and scheduling state.
rpc GetEngineInfo(GetEngineInfoRequest) returns (EngineInfo);
rpc GetServerInfo(GetServerInfoRequest) returns (ServerInfo);
rpc GetModelInfo(GetModelInfoRequest) returns (ModelInfo);
rpc GetLoad(GetLoadRequest) returns (LoadInfo);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

// Engine identity, role, and parallelism metadata.
// Server identity, engine role, and parallelism metadata.

syntax = "proto3";

Expand All @@ -16,12 +16,12 @@ enum EngineRole {
ENGINE_ROLE_DECODE = 3;
}

message GetEngineInfoRequest {}
message GetServerInfoRequest {}

message EngineInfo {
message ServerInfo {
string engine_name = 1; // sglang, vllm, tensorrt_llm, etc.
string engine_version = 2;
EngineRole role = 3;
EngineRole engine_role = 3;
string instance_id = 4;
repeated string supported_models = 5;
ParallelismInfo parallelism = 6;
Expand All @@ -37,4 +37,6 @@ message ParallelismInfo {
optional uint32 data_parallel_size = 3;
optional uint32 data_parallel_rank = 4;
optional uint32 data_parallel_start_rank = 5;
// Number of ranks in each decode-context-parallel group. Must be at least 1.
optional uint32 decode_context_parallel_size = 6;
}
Loading