Skip to content

Commit 423e875

Browse files
authored
Merge branch 'main' into 2169-registry-capacity-counters
2 parents 165bfc7 + 227f6ca commit 423e875

53 files changed

Lines changed: 547 additions & 490 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

pkg/epp/flowcontrol/benchmark/benchmark_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ func BenchmarkFlowController_FullPath(b *testing.B) {
346346
// detector reads to compute saturation.
347347
infReq := &scheduling.InferenceRequest{
348348
RequestID: reqID,
349-
Body: &requesthandling.InferenceRequestBody{TokenizedPrompt: &requesthandling.TokenizedPrompt{PerPromptTokens: [][]uint32{benchTokenIDs}}},
349+
Body: &requesthandling.InferenceRequestBody{TokenizedRequest: &requesthandling.TokenizedRequest{Prompts: []requesthandling.PromptTokens{{TokenIDs: benchTokenIDs}}}},
350350
}
351351
schedResult := &scheduling.SchedulingResult{ProfileResults: profileResults}
352352
_ = h.producer.PreRequest(ctx, infReq, schedResult)

pkg/epp/flowcontrol/integration_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func TestConcurrentSaturationReads(t *testing.T) {
8787
req := &fwksched.InferenceRequest{
8888
RequestID: fmt.Sprintf("req-%d", i),
8989
Body: &fwkrh.InferenceRequestBody{
90-
TokenizedPrompt: &fwkrh.TokenizedPrompt{PerPromptTokens: [][]uint32{make([]uint32, 10)}},
90+
TokenizedRequest: &fwkrh.TokenizedRequest{Prompts: []fwkrh.PromptTokens{{TokenIDs: make([]uint32, 10)}}},
9191
},
9292
}
9393
result := &fwksched.SchedulingResult{
@@ -164,7 +164,7 @@ func TestSaturationFullLoop(t *testing.T) {
164164
req := &fwksched.InferenceRequest{
165165
RequestID: fmt.Sprintf("prefill-%d", i),
166166
Body: &fwkrh.InferenceRequestBody{
167-
TokenizedPrompt: &fwkrh.TokenizedPrompt{PerPromptTokens: [][]uint32{make([]uint32, 50)}},
167+
TokenizedRequest: &fwkrh.TokenizedRequest{Prompts: []fwkrh.PromptTokens{{TokenIDs: make([]uint32, 50)}}},
168168
},
169169
}
170170
result := &fwksched.SchedulingResult{
@@ -453,7 +453,7 @@ func TestUsageLimitThresholdGatesDispatch(t *testing.T) {
453453
req := &fwksched.InferenceRequest{
454454
RequestID: fmt.Sprintf("inflight-%d", i),
455455
Body: &fwkrh.InferenceRequestBody{
456-
TokenizedPrompt: &fwkrh.TokenizedPrompt{PerPromptTokens: [][]uint32{make([]uint32, 10)}},
456+
TokenizedRequest: &fwkrh.TokenizedRequest{Prompts: []fwkrh.PromptTokens{{TokenIDs: make([]uint32, 10)}}},
457457
},
458458
}
459459
result := &fwksched.SchedulingResult{
@@ -1003,7 +1003,7 @@ func TestEndpointReregistrationSaturationAccuracy(t *testing.T) {
10031003
oldReq := &fwksched.InferenceRequest{
10041004
RequestID: "old-req",
10051005
Body: &fwkrh.InferenceRequestBody{
1006-
TokenizedPrompt: &fwkrh.TokenizedPrompt{PerPromptTokens: [][]uint32{make([]uint32, 50)}},
1006+
TokenizedRequest: &fwkrh.TokenizedRequest{Prompts: []fwkrh.PromptTokens{{TokenIDs: make([]uint32, 50)}}},
10071007
},
10081008
}
10091009
oldResult := &fwksched.SchedulingResult{
@@ -1059,7 +1059,7 @@ func TestEndpointReregistrationSaturationAccuracy(t *testing.T) {
10591059
newReq := &fwksched.InferenceRequest{
10601060
RequestID: "new-req",
10611061
Body: &fwkrh.InferenceRequestBody{
1062-
TokenizedPrompt: &fwkrh.TokenizedPrompt{PerPromptTokens: [][]uint32{make([]uint32, 50)}},
1062+
TokenizedRequest: &fwkrh.TokenizedRequest{Prompts: []fwkrh.PromptTokens{{TokenIDs: make([]uint32, 50)}}},
10631063
},
10641064
}
10651065
newResult := &fwksched.SchedulingResult{
@@ -1120,7 +1120,7 @@ func TestEndpointIdentityCollisionDuringPodReplacement(t *testing.T) {
11201120
req := &fwksched.InferenceRequest{
11211121
RequestID: "new-pod-req",
11221122
Body: &fwkrh.InferenceRequestBody{
1123-
TokenizedPrompt: &fwkrh.TokenizedPrompt{PerPromptTokens: [][]uint32{make([]uint32, 50)}},
1123+
TokenizedRequest: &fwkrh.TokenizedRequest{Prompts: []fwkrh.PromptTokens{{TokenIDs: make([]uint32, 50)}}},
11241124
},
11251125
}
11261126
result := &fwksched.SchedulingResult{

pkg/epp/framework/interface/requesthandling/types.go

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,9 @@ type InferenceRequestBody struct {
113113
// If the payload is unmarshaled, we can perform advanced processing (like prefix cache aware routing).
114114
// If it remains as raw bytes, such processing may not be supported.
115115
Payload RequestPayload `json:"-"`
116-
// TokenizedPrompt contains parser-derived tokenization results when available.
116+
// TokenizedRequest contains parser-derived tokenization results when available.
117117
// It is nil when the request was not already tokenized.
118-
TokenizedPrompt *TokenizedPrompt `json:"-"`
118+
TokenizedRequest *TokenizedRequest `json:"-"`
119119

120120
// Stream indicates whether the request specifies a streaming response (e.g., via a stream field).
121121
// This typically implies the model server's response will be streamed.
@@ -189,32 +189,36 @@ func MaxOutputTokensFromPayload(m PayloadMap, keys ...string) *int64 {
189189
return nil
190190
}
191191

192-
// TokenizedPrompt contains the result of tokenizing the request prompt.
192+
// TokenizedRequest contains the result of tokenizing the request prompt.
193193
// It is consumed by scheduling and request-control plugins that benefit from
194194
// actual token data such as prefix-cache awareness.
195-
type TokenizedPrompt struct {
196-
// PerPromptTokens holds the token IDs for each prompt in the request.
197-
// Single-prompt requests (chat, generate, single-string completions) use a
198-
// length-1 outer slice. Multi-string completions use one inner slice per
199-
// prompt string.
200-
PerPromptTokens [][]uint32
201-
// MultiModalFeatures holds one entry per multimodal item in prompt order.
202-
// Nil if the prompt contains no multimodal content. Offsets are relative
203-
// to PerPromptTokens[0] (always single-prompt when multimodal content is
204-
// present).
205-
MultiModalFeatures []MultiModalFeature
195+
type TokenizedRequest struct {
196+
// Prompts holds the per-prompt token data. Single-prompt requests (chat,
197+
// generate, single-string completions) use a length-1 slice. Multi-string
198+
// completions use one entry per prompt string.
199+
Prompts []PromptTokens
206200
// CacheSalt isolates prefix caches across requests. Populated by the token-producer.
207201
CacheSalt string
208202
}
209203

204+
// PromptTokens bundles the token IDs and multimodal features for a single
205+
// prompt in the request.
206+
type PromptTokens struct {
207+
// TokenIDs holds the token IDs for this prompt.
208+
TokenIDs []uint32
209+
// MultiModalFeatures holds multimodal items for this prompt, ordered by
210+
// token position. Nil if the prompt contains no multimodal content.
211+
MultiModalFeatures []MultiModalFeature
212+
}
213+
210214
// TokenCount returns the total number of tokens across all prompts.
211-
func (tp *TokenizedPrompt) TokenCount() int {
215+
func (tp *TokenizedRequest) TokenCount() int {
212216
if tp == nil {
213217
return 0
214218
}
215219
n := 0
216-
for _, pp := range tp.PerPromptTokens {
217-
n += len(pp)
220+
for _, p := range tp.Prompts {
221+
n += len(p.TokenIDs)
218222
}
219223
return n
220224
}
@@ -227,9 +231,10 @@ type MultiModalFeature struct {
227231
Modality Modality
228232
// Hash is the content hash of the item, used for KV-cache reuse across requests.
229233
Hash string
230-
// Offset is the index of the first placeholder token for this item in TokenIDs.
234+
// Offset is the index of the first placeholder token for this item
235+
// in the owning PromptTokens.TokenIDs slice.
231236
Offset int
232-
// Length is the number of placeholder tokens this item occupies in TokenIDs.
237+
// Length is the number of placeholder tokens this item occupies.
233238
Length int
234239
}
235240

pkg/epp/framework/interface/scheduling/types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ type Modality = fwkrh.Modality
3333

3434
const ModalityImage = fwkrh.ModalityImage
3535

36-
type TokenizedPrompt = fwkrh.TokenizedPrompt
36+
type TokenizedRequest = fwkrh.TokenizedRequest
3737

3838
type MultiModalFeature = fwkrh.MultiModalFeature
3939

pkg/epp/framework/observability/multimodal/multimodal.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,12 @@ func Summary(req *scheduling.InferenceRequest) (modality string, hashCount int)
6767
}
6868

6969
func requestMMFeatures(req *scheduling.InferenceRequest) []fwkrh.MultiModalFeature {
70-
if req == nil || req.Body == nil || req.Body.TokenizedPrompt == nil {
70+
if req == nil || req.Body == nil || req.Body.TokenizedRequest == nil {
7171
return nil
7272
}
73-
return req.Body.TokenizedPrompt.MultiModalFeatures
73+
var features []fwkrh.MultiModalFeature
74+
for _, p := range req.Body.TokenizedRequest.Prompts {
75+
features = append(features, p.MultiModalFeatures...)
76+
}
77+
return features
7478
}

pkg/epp/framework/observability/multimodal/multimodal_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,10 @@ func TestSpanAttributes(t *testing.T) {
109109
func requestWith(features ...fwkrh.MultiModalFeature) *scheduling.InferenceRequest {
110110
return &scheduling.InferenceRequest{
111111
Body: &fwkrh.InferenceRequestBody{
112-
TokenizedPrompt: &fwkrh.TokenizedPrompt{
113-
MultiModalFeatures: features,
112+
TokenizedRequest: &fwkrh.TokenizedRequest{
113+
Prompts: []fwkrh.PromptTokens{{
114+
MultiModalFeatures: features,
115+
}},
114116
},
115117
},
116118
}

pkg/epp/framework/plugins/flowcontrol/saturationdetector/concurrency/detector_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -809,7 +809,7 @@ func makeTokenRequest(requestID string, inputTokens int) *fwksched.InferenceRequ
809809
return &fwksched.InferenceRequest{
810810
RequestID: requestID,
811811
Body: &fwkrh.InferenceRequestBody{
812-
TokenizedPrompt: &fwkrh.TokenizedPrompt{PerPromptTokens: [][]uint32{make([]uint32, inputTokens)}},
812+
TokenizedRequest: &fwkrh.TokenizedRequest{Prompts: []fwkrh.PromptTokens{{TokenIDs: make([]uint32, inputTokens)}}},
813813
},
814814
}
815815
}

pkg/epp/framework/plugins/requestcontrol/dataproducer/approximateprefix/plugin.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,12 +126,12 @@ func (p *dataProducer) Produces() map[plugin.DataKey]any {
126126
return map[plugin.DataKey]any{p.dk: attrprefix.PrefixCacheMatchInfo{}}
127127
}
128128

129-
// Consumes declares the TokenizedPrompt dependency so the data-layer DAG orders
129+
// Consumes declares the TokenizedRequest dependency so the data-layer DAG orders
130130
// the token-producer before this producer runs and auto-creates one when none
131131
// is configured.
132132
func (p *dataProducer) Consumes() plugin.DataDependencies {
133133
return plugin.DataDependencies{
134-
Required: map[plugin.DataKey]any{tokenproducer.TokenizedPromptDataKey: fwksched.TokenizedPrompt{}},
134+
Required: map[plugin.DataKey]any{tokenproducer.TokenizedPromptDataKey: fwksched.TokenizedRequest{}},
135135
}
136136
}
137137

pkg/epp/framework/plugins/requestcontrol/dataproducer/approximateprefix/plugin_test.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func disableMinBlockSizeClamp(t *testing.T) {
5353
// tokenizedBody returns a request body carrying only a tokenized prompt.
5454
func tokenizedBody(tokenIDs []uint32) *fwkrh.InferenceRequestBody {
5555
return &fwkrh.InferenceRequestBody{
56-
TokenizedPrompt: &fwkrh.TokenizedPrompt{PerPromptTokens: [][]uint32{tokenIDs}},
56+
TokenizedRequest: &fwkrh.TokenizedRequest{Prompts: []fwkrh.PromptTokens{{TokenIDs: tokenIDs}}},
5757
}
5858
}
5959

@@ -663,8 +663,8 @@ func TestProduce_MultiPrompt(t *testing.T) {
663663
RequestID: uuid.NewString(),
664664
TargetModel: "test-model",
665665
Body: &fwkrh.InferenceRequestBody{
666-
TokenizedPrompt: &fwkrh.TokenizedPrompt{
667-
PerPromptTokens: [][]uint32{{1, 2, 3}, {4, 5}},
666+
TokenizedRequest: &fwkrh.TokenizedRequest{
667+
Prompts: []fwkrh.PromptTokens{{TokenIDs: []uint32{1, 2, 3}}, {TokenIDs: []uint32{4, 5}}},
668668
},
669669
},
670670
}
@@ -706,8 +706,8 @@ func TestMultiPromptMatchAggregation(t *testing.T) {
706706
RequestID: uuid.NewString(),
707707
TargetModel: "test-model",
708708
Body: &fwkrh.InferenceRequestBody{
709-
TokenizedPrompt: &fwkrh.TokenizedPrompt{
710-
PerPromptTokens: [][]uint32{{1, 2, 3}, {4, 5}},
709+
TokenizedRequest: &fwkrh.TokenizedRequest{
710+
Prompts: []fwkrh.PromptTokens{{TokenIDs: []uint32{1, 2, 3}}, {TokenIDs: []uint32{4, 5}}},
711711
},
712712
},
713713
}
@@ -725,8 +725,8 @@ func TestMultiPromptMatchAggregation(t *testing.T) {
725725
RequestID: uuid.NewString(),
726726
TargetModel: "test-model",
727727
Body: &fwkrh.InferenceRequestBody{
728-
TokenizedPrompt: &fwkrh.TokenizedPrompt{
729-
PerPromptTokens: [][]uint32{{1, 2, 3}, {4, 5}},
728+
TokenizedRequest: &fwkrh.TokenizedRequest{
729+
Prompts: []fwkrh.PromptTokens{{TokenIDs: []uint32{1, 2, 3}}, {TokenIDs: []uint32{4, 5}}},
730730
},
731731
},
732732
}
@@ -759,8 +759,8 @@ func TestMultiPromptPartialMatch(t *testing.T) {
759759
RequestID: uuid.NewString(),
760760
TargetModel: "test-model",
761761
Body: &fwkrh.InferenceRequestBody{
762-
TokenizedPrompt: &fwkrh.TokenizedPrompt{
763-
PerPromptTokens: [][]uint32{{1, 2}, {3, 4}},
762+
TokenizedRequest: &fwkrh.TokenizedRequest{
763+
Prompts: []fwkrh.PromptTokens{{TokenIDs: []uint32{1, 2}}, {TokenIDs: []uint32{3, 4}}},
764764
},
765765
},
766766
}
@@ -778,8 +778,8 @@ func TestMultiPromptPartialMatch(t *testing.T) {
778778
RequestID: uuid.NewString(),
779779
TargetModel: "test-model",
780780
Body: &fwkrh.InferenceRequestBody{
781-
TokenizedPrompt: &fwkrh.TokenizedPrompt{
782-
PerPromptTokens: [][]uint32{{1, 2}, {5, 6}},
781+
TokenizedRequest: &fwkrh.TokenizedRequest{
782+
Prompts: []fwkrh.PromptTokens{{TokenIDs: []uint32{1, 2}}, {TokenIDs: []uint32{5, 6}}},
783783
},
784784
},
785785
}

pkg/epp/framework/plugins/requestcontrol/dataproducer/burstprefix/plugin.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,11 @@ func (p *dataProducer) Produces() map[plugin.DataKey]any {
7373
return map[plugin.DataKey]any{p.dk: attrprefix.PrefixCacheMatchInfo{}}
7474
}
7575

76-
// Consumes declares the TokenizedPrompt dependency so the token-producer runs
76+
// Consumes declares the TokenizedRequest dependency so the token-producer runs
7777
// before this producer and one is auto-created when none is configured.
7878
func (p *dataProducer) Consumes() plugin.DataDependencies {
7979
return plugin.DataDependencies{
80-
Required: map[plugin.DataKey]any{tokenproducer.TokenizedPromptDataKey: fwksched.TokenizedPrompt{}},
80+
Required: map[plugin.DataKey]any{tokenproducer.TokenizedPromptDataKey: fwksched.TokenizedRequest{}},
8181
}
8282
}
8383

0 commit comments

Comments
 (0)