Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
122 commits
Select commit Hold shift + click to select a range
4cb33d1
feat: support local systems roots in predict and recommend
Arsene12358 Sep 14, 2026
dcb73f9
feat: add independent guided FPM onboarding workflow
Arsene12358 Sep 14, 2026
3cb22fd
Merge main into guided FPM support and preserve local hardware lookups
Arsene12358 Sep 16, 2026
caca6d0
docs: guide model integration for FPM onboarding
Arsene12358 Sep 16, 2026
ecb6ee5
fix: guard guided FPM collection and recover interrupted plans
Arsene12358 Sep 16, 2026
b4af59d
fix: report unexpected FPM collection failures cleanly
Arsene12358 Sep 16, 2026
d6650fd
test: assert local FPM timing for worker overrides
Arsene12358 Sep 16, 2026
29a19ae
fix: preserve installed-wheel imports in recommendation tests
Arsene12358 Sep 16, 2026
dffb80d
feat: name model and hardware FPM onboarding explicitly
Arsene12358 Sep 16, 2026
949c0df
Merge main to align CI and release contracts
Arsene12358 Sep 16, 2026
24486a9
fix: use onboard as the sole model onboarding command
Arsene12358 Sep 16, 2026
396af2d
fix: reject nested symlinks in onboarding collection outputs
Arsene12358 Sep 16, 2026
661fd97
docs: rename onboarding guide to FPM self-service
Arsene12358 Sep 16, 2026
f5a3ac0
docs: align FPM onboarding with planned model decoupling
Arsene12358 Sep 16, 2026
d338ebc
docs: make analytical integration an optional FPM route
Arsene12358 Sep 16, 2026
4393596
feat: decouple FPM workflows from analytical model classes
Arsene12358 Sep 16, 2026
081eb51
fix: preserve FPM profile identity across SDK namespaces
Arsene12358 Sep 16, 2026
cdafa00
ci: assign ownership for FPM profile workflow tests
Arsene12358 Sep 16, 2026
632f523
feat: derive FPM onboarding profiles from model configs
Arsene12358 Sep 17, 2026
81d889e
fix: validate KV cache type during config onboarding
Arsene12358 Sep 17, 2026
e8030c0
feat: review and edit FPM profiles before guided save
Arsene12358 Sep 17, 2026
e19a9c6
docs: guide agents through FPM model onboarding
Arsene12358 Sep 18, 2026
a47eafd
docs: focus FPM self-service guide on external users
Arsene12358 Sep 18, 2026
70b2b91
docs: structure agent onboarding into six stages
Arsene12358 Sep 18, 2026
7674fe5
docs: ask for Hugging Face model ID during onboarding
Arsene12358 Sep 18, 2026
1e92af9
Merge canonical estimator APIs into guided FPM onboarding
Arsene12358 Sep 18, 2026
13e4290
Merge canonical estimator API into FPM decoupling workflow
Arsene12358 Sep 18, 2026
c1316f6
Merge canonical FPM configuration into model onboarding
Arsene12358 Sep 18, 2026
fd2d20f
Keep FPM configuration parsing inside the lightweight supervision bou…
Arsene12358 Sep 18, 2026
1b448ac
Preserve lightweight configuration parsing in model onboarding
Arsene12358 Sep 18, 2026
72f21b3
feat: onboard multimodal checkpoints for text-only FPM
Arsene12358 Sep 18, 2026
efa53b0
Separate FPM onboarding collection scope from deployment allocation
Arsene12358 Sep 19, 2026
cf4eaf7
feat: suggest FPM onboarding topologies from model and hardware
Arsene12358 Sep 19, 2026
05bf614
Merge main into guided FPM onboarding
Arsene12358 Sep 19, 2026
8d798b1
Merge updated onboarding foundation into FPM decoupling
Arsene12358 Sep 19, 2026
45574cd
Merge updated FPM decoupling into config onboarding
Arsene12358 Sep 19, 2026
10186e3
feat: validate FPM onboarding with aggregated AgentX replay
Arsene12358 Sep 19, 2026
d03a09f
docs: fold model integration guide into FPM onboarding
Arsene12358 Sep 19, 2026
c654bf0
docs: clarify shared FPM collection policy
Arsene12358 Sep 19, 2026
b02a622
feat: support grouped FPM cache in onboarding and replay
Arsene12358 Sep 19, 2026
27c682a
fix: declare native FPM cache budget typing
Arsene12358 Sep 19, 2026
1d1b6f8
feat: onboard multiple FPM parallel configurations
Arsene12358 Sep 19, 2026
74e9291
feat: refine FPM onboarding runtime defaults
Arsene12358 Sep 20, 2026
fc03822
docs: require proactive runtime and precision investigation
Arsene12358 Sep 20, 2026
2353a74
feat: checkpoint FPM onboarding sessions
Arsene12358 Sep 20, 2026
8a348b7
feat: resolve FPM onboarding memory from runtime evidence
Arsene12358 Sep 21, 2026
7f7cd55
Merge main into guided FPM onboarding
Arsene12358 Sep 22, 2026
4d702ff
feat(onboard): expose existing Slurm FPM collection executor
Arsene12358 Sep 22, 2026
145aaf3
Merge updated onboarding foundation into FPM decoupling
Arsene12358 Sep 22, 2026
b09d365
Merge refreshed FPM decoupling base into onboarding
Arsene12358 Sep 22, 2026
ae44d00
fix: verify profile runtime versions in Slurm collection
Arsene12358 Sep 22, 2026
f1f33ca
merge: carry Slurm profile version validation into onboarding
Arsene12358 Sep 22, 2026
cc070c7
fix: preserve FPM collection identity through Slurm finalization
Arsene12358 Sep 22, 2026
987468e
merge: align onboarding resource admission test contract
Arsene12358 Sep 22, 2026
2e02467
test: permit lightweight FPM metadata before resource admission
Arsene12358 Sep 22, 2026
1f4df9f
fix: retain frozen Slurm deployment during onboarding finalization
Arsene12358 Sep 22, 2026
9240b3c
fix: clarify onboarding executor prerequisites and source provenance
Arsene12358 Sep 22, 2026
71487eb
fix: use absolute env entrypoint for Slurm containers
Arsene12358 Sep 22, 2026
ad66933
test: update onboarding Slurm command fixture
Arsene12358 Sep 22, 2026
978ae0b
fix: enable FPM KV warm-up by default in both phases
Arsene12358 Sep 22, 2026
d81d3c6
feat: validate FPM onboarding with editable campaign policies
Arsene12358 Sep 22, 2026
cae514e
fix: honor editable onboarding error thresholds consistently
Arsene12358 Sep 22, 2026
fa76b1c
fix: preserve explicit unquantized KV cache metadata
Arsene12358 Sep 22, 2026
a82875d
feat: add campaign-local runtime probes for FPM onboarding
Arsene12358 Sep 23, 2026
83ae61a
fix: preserve native runtime observations through FPM validation
Arsene12358 Sep 23, 2026
a8caa64
fix: bound finalized runtime provenance in recommendation checkpoints
Arsene12358 Sep 23, 2026
583b0ba
fix: preserve FPM ComputeDomain ownership labels
Arsene12358 Sep 24, 2026
8b975f3
docs: guide independent FPM collection campaigns
Arsene12358 Sep 24, 2026
07e9a72
fix: accept zero-KV prefill provenance in FPM artifacts
Arsene12358 Sep 24, 2026
a6fdb4c
fix: preserve explicit CUDA graphs in FPM smoke collection
Arsene12358 Sep 24, 2026
0d657a4
feat: gate FPM onboarding on native timing readiness
Arsene12358 Sep 24, 2026
a559d9e
docs: guide FPM timing readiness and campaign recovery
Arsene12358 Sep 24, 2026
3908362
test: align readiness imports with repository lint rules
Arsene12358 Sep 24, 2026
03a9fc5
fix: consolidate zero-KV prefill provenance duplicates
Arsene12358 Sep 25, 2026
688e2f9
fix(onboard): reuse verified FPM collection for stage 5 validation
Arsene12358 Sep 25, 2026
cf7a905
fix(onboard): retain execution boundaries in holdout validation
Arsene12358 Sep 25, 2026
54f1422
fix: allocate and validate CPU affinity for FPM onboarding
Arsene12358 Sep 26, 2026
c51bdb1
fix: validate FPM repeatability with matched full sweeps
Arsene12358 Sep 28, 2026
45fa257
fix: address FPM onboarding review feedback
Arsene12358 Sep 28, 2026
c77ca53
fix(fpm): recognize pinned Hugging Face cache snapshots
Arsene12358 Sep 28, 2026
e29290b
docs: require evidence for DP imbalance exclusions
Arsene12358 Sep 28, 2026
6cdfaee
fix: align onboarding metadata and runtime evidence
Arsene12358 Sep 28, 2026
8f31886
fix: address FPM profile review feedback
Arsene12358 Sep 28, 2026
3e7d1d2
fix: complete the detailed FPM API declaration
Arsene12358 Sep 28, 2026
e94b14a
Harden FPM onboarding evidence and quality validation
Arsene12358 Sep 28, 2026
27468bb
merge: sync FPM onboarding with decoupling updates
Arsene12358 Sep 29, 2026
3dc5483
feat: onboard independent FPM serving roles
Arsene12358 Sep 29, 2026
9c0f645
fix: preserve FPM role in topology suggestions
Arsene12358 Sep 29, 2026
a4f9c3f
fix: accept pinned Hugging Face snapshots in runtime probes
Arsene12358 Sep 29, 2026
bd96d2f
Merge main into feat/guided-fpm-cli
simone-chen Sep 29, 2026
6236b65
fix: preserve worker data roots in performance metadata
simone-chen Sep 29, 2026
a7c1ccd
docs: fix renamed FPM collection guide link
simone-chen Sep 29, 2026
d1262e1
docs: align FPM onboarding with self-benchmarking guide
Arsene12358 Sep 30, 2026
020e4bb
Merge updated FPM foundation into decoupling
Arsene12358 Sep 30, 2026
ab0587b
Merge main into feat/fpm-model-decoupling
simone-chen Sep 30, 2026
d81b256
ci: assign ownership for FPM query evidence tests
simone-chen Sep 30, 2026
8a4a804
fix: enforce profile decode collection bounds
simone-chen Sep 30, 2026
346aaea
Merge updated FPM model decoupling into self-service onboarding
simone-chen Sep 30, 2026
0774f85
Merge maintainer updates into FPM decoupling integration
Arsene12358 Sep 30, 2026
2806935
Merge FPM review fixes and ownership updates
simone-chen Sep 30, 2026
65878d9
Merge refreshed FPM decoupling into onboarding
Arsene12358 Sep 30, 2026
ab75597
test: align onboarding integration checks with merged runtime contracts
simone-chen Sep 30, 2026
e19ad8c
Merge reconciled FPM base into onboarding
Arsene12358 Sep 30, 2026
c164565
fix: preserve FPM options and enforce qualified API boundaries
simone-chen Sep 30, 2026
b6c60fd
Merge decode collection bounds into FPM decoupling integration
Arsene12358 Sep 30, 2026
4542c81
Merge FPM option migration and API boundary fixes
simone-chen Sep 30, 2026
27f3f27
Merge qualified FPM API guards into decoupling integration
Arsene12358 Sep 30, 2026
d7aba90
Merge reviewed collection bounds into onboarding integration
Arsene12358 Sep 30, 2026
6b9703e
Merge reviewed FPM API guard reconciliation into onboarding
Arsene12358 Sep 30, 2026
c50b487
Refresh onboarding integration and preserve collector CLI failure con…
Arsene12358 Sep 30, 2026
b946545
test: include FPM profile in positional config expectations
Arsene12358 Sep 30, 2026
34536ec
Merge positional config fixture correction from FPM decoupling
Arsene12358 Sep 30, 2026
9d8b695
docs: clarify FPM engine spec schema migration
simone-chen Sep 30, 2026
29223c7
Merge main into FPM decoupling before merge
simone-chen Sep 30, 2026
bbd80a5
Merge final FPM decoupling fixes and current scheduler updates
simone-chen Sep 30, 2026
4d4e9b4
Merge latest CI pipeline fixes before FPM merge
simone-chen Sep 30, 2026
e6ee81d
Merge final reviewed FPM decoupling branch
simone-chen Sep 30, 2026
d84c824
Merge current main changes before squash ancestry reconciliation
simone-chen Sep 30, 2026
40fa406
Reconcile squash-merged FPM decoupling ancestry
simone-chen Sep 30, 2026
d6e0c2e
test: preserve worker roles in heterogeneous search mock
simone-chen Sep 30, 2026
b323dbd
fix: address final FPM onboarding review findings
simone-chen Sep 30, 2026
9e5f925
fix: select flat FPM deployment before checking runner support
simone-chen Sep 30, 2026
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
6 changes: 6 additions & 0 deletions .github/codeowners/areas.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ areas:
github_team: "@ai-dynamo/access-aisimulate-maintain"
path_globs:
- AGENTS.md
- CLAUDE.md
- CODE_OF_CONDUCT.md
- DEVELOPMENT.md
- LICENSE
Expand All @@ -34,6 +35,7 @@ areas:
- python/aisimulate/src/aisimulate/capacity.py
- tests/test_aic.py
- tests/test_fpm_profile_workflow.py
- tests/test_fpm_grouped_workflow.py
- tests/test_fpm_query_evidence.py
- label: sweeper
github_team: "@ai-dynamo/aisimulate-sweeper-codeowners"
Expand Down Expand Up @@ -162,6 +164,8 @@ shared:
owners: [forward-pass-engine, maintainers]
- glob: tests/test_fpm_profile_workflow.py
owners: [forward-pass-engine, maintainers]
- glob: tests/test_fpm_grouped_workflow.py
owners: [forward-pass-engine, maintainers]
- glob: tests/test_fpm_query_evidence.py
owners: [forward-pass-engine, replay, maintainers]
- glob: python/aisimulate/src/aisimulate/sweeper/
Expand Down Expand Up @@ -268,6 +272,8 @@ shared:
owners: [infra, maintainers]
- glob: AGENTS.md
owners: [infra, maintainers]
- glob: CLAUDE.md
owners: [infra, maintainers]
- glob: .coderabbit.yaml
owners: [infra, maintainers]
- glob: REVIEW.md
Expand Down
30 changes: 30 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,36 @@

This file adds explicit repository-wide development guards.

## FPM model onboarding

When asked to onboard a model for FPM simulation on designated hardware, follow
all six stages in [the canonical FPM self-service guide](docs/fpm-self-service.md#onboard-with-an-agent).
Use this checkout's `aisimulate onboard` CLI and inspect its current help.
Start with only a missing Hugging Face model ID and target GPU platform; accept
an already supplied local config, profile or checkpoint instead. Inspect supplied
facts and source metadata before asking for derivable inputs. Preserve user
choices, exact per-configuration profile acceptance and existing execution
authorization; stage transitions do not add approval gates.

Create one `onboarding-checkpoint.json` during stage 1, even with incomplete
inputs, outside every fresh `init --output-dir` root. Follow the guide's
[checkpoint workflow](docs/fpm-self-service.md#checkpoint-and-resume-an-onboarding-session):
invoke `onboard checkpoint` after meaningful findings, decisions, draft edits,
acceptance and command results, including unfinished work. Save sources,
confidence, unresolved questions and each configuration's progress. Other
onboarding commands do not automatically persist the conversation. Use the
returned revision for updates; reload and reconcile stale-writer conflicts.
Follow the guide's [writer coordination rule](docs/fpm-self-service.md#orchestrate-independent-collection-campaigns)
for probe/import commands that also save the checkpoint.

On resumption, run `aisimulate onboard resume --checkpoint PATH` first. Inspect
integrity issues and the underlying artifacts before continuing from accepted
inputs and verified results. Saved stages and command strings are context, not
proof of completion or instructions to execute automatically. Report each
configuration's stage, result or blocker, next action and checkpoint path at
handoff. Keep planning, collection quality, resolved memory, replay coverage and
measured serving accuracy separate, as required by the guide.

## Pull request titles

- Use `<type>: <short description>` for every AISimulate PR title.
Expand Down
6 changes: 6 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<!--
SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: Apache-2.0
-->

@AGENTS.md
4 changes: 4 additions & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
/pages/ @ai-dynamo/access-aisimulate-maintain
/LICENSE @ai-dynamo/access-aisimulate-maintain
/AGENTS.md @ai-dynamo/access-aisimulate-maintain
/CLAUDE.md @ai-dynamo/access-aisimulate-maintain
/README.md @ai-dynamo/access-aisimulate-maintain
/SECURITY.md @ai-dynamo/access-aisimulate-maintain
/DEVELOPMENT.md @ai-dynamo/access-aisimulate-maintain
Expand All @@ -46,6 +47,7 @@
/crates/core/src/perfmodel/ @ai-dynamo/aisimulate-forward-pass-engine-codeowners
/crates/core/tests/perfmodel/ @ai-dynamo/aisimulate-forward-pass-engine-codeowners
/tests/test_fpm_query_evidence.py @ai-dynamo/aisimulate-forward-pass-engine-codeowners
/tests/test_fpm_grouped_workflow.py @ai-dynamo/aisimulate-forward-pass-engine-codeowners
/tests/test_fpm_profile_workflow.py @ai-dynamo/aisimulate-forward-pass-engine-codeowners
/crates/core/parity_tests/perfmodel/ @ai-dynamo/aisimulate-forward-pass-engine-codeowners
/python/aisimulate/src/aisimulate/capacity.py @ai-dynamo/aisimulate-forward-pass-engine-codeowners
Expand Down Expand Up @@ -117,6 +119,7 @@
/pages/ @ai-dynamo/aisimulate-forward-pass-engine-codeowners @ai-dynamo/aisimulate-infra-codeowners @ai-dynamo/access-aisimulate-maintain
/scripts/ @ai-dynamo/aisimulate-infra-codeowners @ai-dynamo/access-aisimulate-maintain
/AGENTS.md @ai-dynamo/aisimulate-infra-codeowners @ai-dynamo/access-aisimulate-maintain
/CLAUDE.md @ai-dynamo/aisimulate-infra-codeowners @ai-dynamo/access-aisimulate-maintain
/REVIEW.md @ai-dynamo/aisimulate-infra-codeowners @ai-dynamo/access-aisimulate-maintain
/deny.toml @ai-dynamo/aisimulate-infra-codeowners @ai-dynamo/access-aisimulate-maintain
/CODEOWNERS @ai-dynamo/aisimulate-infra-codeowners @ai-dynamo/access-aisimulate-maintain
Expand Down Expand Up @@ -188,6 +191,7 @@
/python/aisimulate/.coderabbit.yaml @ai-dynamo/aisimulate-infra-codeowners @ai-dynamo/access-aisimulate-maintain
/python/aisimulate/eslint.config.js @ai-dynamo/aisimulate-infra-codeowners @ai-dynamo/access-aisimulate-maintain
/tests/test_e2e_accuracy_nightly.py @ai-dynamo/aisimulate-forward-pass-engine-codeowners @ai-dynamo/aisimulate-replay-codeowners @ai-dynamo/aisimulate-infra-codeowners @ai-dynamo/access-aisimulate-maintain
/tests/test_fpm_grouped_workflow.py @ai-dynamo/aisimulate-forward-pass-engine-codeowners @ai-dynamo/access-aisimulate-maintain
/tests/test_fpm_profile_workflow.py @ai-dynamo/aisimulate-forward-pass-engine-codeowners @ai-dynamo/access-aisimulate-maintain
/tests/test_resource_supervision.py @ai-dynamo/aisimulate-replay-codeowners @ai-dynamo/aisimulate-sweeper-codeowners @ai-dynamo/access-aisimulate-maintain
/crates/core/parity_tests/perfmodel/ @ai-dynamo/aisimulate-forward-pass-engine-codeowners @ai-dynamo/access-aisimulate-maintain
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ APIs:
- [Estimator/FPE Python and Rust SDK](docs/core-api.md)
- [FPM self-service: onboard a model on target hardware](docs/fpm-self-service.md)
- [AIC-compatible modeled-power contract (semantics only)](docs/power-model.md)
- [Self-benchmarking and FPM onboarding guide](python/aisimulate/docs/fpm/self-benchmarking-and-onboarding.md)
- [FPM self-benchmarking and onboarding guide](python/aisimulate/docs/fpm/self-benchmarking-and-onboarding.md)
- [Replay SDK and artifact contract](crates/core/src/replay/README.md)
- [Sweeper SDK](docs/sweeper/overview.md)
- [Legacy CLI reference](docs/cli/legacy-aic-user-guide.md)
Expand Down
23 changes: 23 additions & 0 deletions THIRD_PARTY_NOTICES.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,29 @@ https://gitlab-master.nvidia.com/dl/sglang/sglang/-/blob/02c5a855aceb968c310e6fb

## vLLM

The grouped-cache config derivation and metadata regression tests in
`src/aisimulate/support/config_profile.py`,
`tests/unit/test_support_config_profile.py`, and
`tests/unit/test_support_topology.py` are adapted and modified from vLLM's
Inkling cache layout, decoder state construction, and configuration defaults at
commit `98dff2a81d747d1dba01a47f939f48c3526d4206`:

- [`vllm/models/inkling/nvidia/sconv_swa_attn.py`](https://github.com/vllm-project/vllm/blob/98dff2a81d747d1dba01a47f939f48c3526d4206/vllm/models/inkling/nvidia/sconv_swa_attn.py)
- [`vllm/models/inkling/nvidia/model.py`](https://github.com/vllm-project/vllm/blob/98dff2a81d747d1dba01a47f939f48c3526d4206/vllm/models/inkling/nvidia/model.py)
- [`vllm/models/inkling/configs.py`](https://github.com/vllm-project/vllm/blob/98dff2a81d747d1dba01a47f939f48c3526d4206/vllm/models/inkling/configs.py)

Copyright contributors to the vLLM project.

This material is licensed under Apache-2.0; the upstream license at the
identified revision is available at:
https://github.com/vllm-project/vllm/blob/98dff2a81d747d1dba01a47f939f48c3526d4206/LICENSE

AISimulate modifies these contracts for metadata-only rank-local aggregate
cache sizing and validation, without constructing runtime tensors or a model.
The derived tests use original synthetic geometries and do not copy a
checkpoint fixture. The derived files retain the upstream copyright and
identify the modified source material.

The repository-root files `crates/core/src/engine/scheduler/vllm/core.rs`,
`crates/core/src/engine/kv_manager/{state_cache_manager,vllm_backend}.rs`,
`crates/core/src/engine/cache/vllm_block_pool.rs`,
Expand Down
4 changes: 4 additions & 0 deletions crates/core/src/engine/common/protocols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,10 @@ pub(crate) struct MockEngineArgs {
pub kv_transfer_bytes_per_token: Option<usize>,
#[builder(default = "None")]
pub kv_cache_bytes_per_token: Option<usize>,
#[builder(default)]
pub kv_cache_groups: Vec<crate::perfmodel::FpmCacheGroup>,
#[builder(default = "None")]
pub kv_cache_capacity_bytes: Option<u64>,
#[builder(default = "None")]
pub native_host_offload: Option<NativeHostOffloadConfig>,
#[builder(default = "None")]
Expand Down
118 changes: 117 additions & 1 deletion crates/core/src/engine/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use serde::{Deserialize, Deserializer, Serialize};
use crate::engine::common::speculative::normalize_conditional_accept_rates;
use crate::engine::handoff::TransferTimingMode;
use crate::engine::timing::{TimingModel, TimingModelConfig, built_in_timing_model};
use crate::perfmodel::FpmCacheGroup;

const DEFAULT_MAX_PREFILL_TOKENS: usize = 16_384;
const DEFAULT_CHUNKED_PREFILL_SIZE: usize = 8_192;
Expand Down Expand Up @@ -371,7 +372,8 @@ pub struct EngineConfig {
/// Use [`Self::for_backend`] instead of changing this field on
/// [`Self::default`] when backend-dependent defaults are desired.
pub backend: Backend,
/// Physical G1 capacity in blocks.
/// Physical G1 capacity in blocks for a linear cache. Retained as a
/// positive compatibility field and ignored when `kv_cache_groups` is set.
#[serde(default = "default_num_gpu_blocks")]
pub num_gpu_blocks: usize,
/// KV block size in tokens.
Expand Down Expand Up @@ -429,6 +431,12 @@ pub struct EngineConfig {
/// Physical KV-cache bytes occupied by one token for host offload.
#[serde(skip_serializing_if = "Option::is_none")]
pub kv_cache_bytes_per_token: Option<usize>,
/// Rank-local cache group geometry. An empty list retains the linear pool.
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub kv_cache_groups: Vec<FpmCacheGroup>,
/// Shared physical budget for `kv_cache_groups`, including page padding.
#[serde(skip_serializing_if = "Option::is_none")]
pub kv_cache_capacity_bytes: Option<u64>,
/// Optional framework-native host-offload simulation.
#[serde(skip_serializing_if = "Option::is_none")]
pub native_host_offload: Option<NativeHostOffloadConfig>,
Expand Down Expand Up @@ -502,6 +510,10 @@ struct EngineConfigWire {
kv_transfer_bytes_per_token: Option<usize>,
#[serde(default, skip_serializing_if = "Option::is_none")]
kv_cache_bytes_per_token: Option<usize>,
#[serde(default)]
kv_cache_groups: Vec<FpmCacheGroup>,
#[serde(default)]
kv_cache_capacity_bytes: Option<u64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
native_host_offload: Option<NativeHostOffloadConfig>,
#[serde(default, skip_serializing_if = "Option::is_none")]
Expand Down Expand Up @@ -563,6 +575,8 @@ impl<'de> Deserialize<'de> for EngineConfig {
emit_kv_token_ids: wire.emit_kv_token_ids,
kv_transfer_bytes_per_token: wire.kv_transfer_bytes_per_token,
kv_cache_bytes_per_token: wire.kv_cache_bytes_per_token,
kv_cache_groups: wire.kv_cache_groups,
kv_cache_capacity_bytes: wire.kv_cache_capacity_bytes,
native_host_offload: wire.native_host_offload,
g3_offload: wire.g3_offload,
state_cache: wire.state_cache,
Expand Down Expand Up @@ -604,6 +618,8 @@ impl Default for EngineConfig {
emit_kv_token_ids: false,
kv_transfer_bytes_per_token: None,
kv_cache_bytes_per_token: None,
kv_cache_groups: Vec::new(),
kv_cache_capacity_bytes: None,
native_host_offload: None,
g3_offload: None,
state_cache: None,
Expand Down Expand Up @@ -761,6 +777,49 @@ impl EngineConfig {
self.kv_cache_bytes_per_token.is_none_or(|bytes| bytes > 0),
"kv_cache_bytes_per_token must be positive"
);
if self.kv_cache_groups.is_empty() {
ensure!(
self.kv_cache_capacity_bytes.is_none(),
"kv_cache_capacity_bytes requires kv_cache_groups"
);
} else {
ensure!(
self.backend == Backend::Vllm && self.worker_type == WorkerType::Aggregated,
"kv_cache_groups currently require backend=vllm and worker_type=aggregated"
);
ensure!(
!self.enable_prefix_caching,
"kv_cache_groups currently require enable_prefix_caching=false"
);
ensure!(
self.native_host_offload.is_none() && self.g3_offload.is_none(),
"kv_cache_groups currently support only HBM without host or G3 offload"
);
ensure!(
self.aic_nextn.is_none(),
"kv_cache_groups currently do not support speculative decoding"
);
ensure!(
!self.emit_kv_events && !self.emit_kv_token_ids,
"kv_cache_groups currently do not support KV event or token-ID emission"
);
ensure!(
self.kv_cache_bytes_per_token.is_none()
&& self.kv_transfer_bytes_per_token.is_none()
&& self.kv_transfer_bandwidth.is_none(),
"kv_cache_groups cannot use linear cache or KV transfer byte geometry"
);
ensure!(
self.kv_cache_capacity_bytes
.is_some_and(|bytes| bytes > 0 && bytes <= (1u64 << 53)),
"kv_cache_groups require positive kv_cache_capacity_bytes at most 2^53"
);
let mut names = std::collections::HashSet::new();
for group in &self.kv_cache_groups {
group.validate()?;
ensure!(names.insert(&group.name), "duplicate KV cache group name");
}
}
if let Some(g3) = &self.g3_offload {
g3.validate()?;
anyhow::ensure!(
Expand Down Expand Up @@ -1184,6 +1243,63 @@ mod tests {
assert!(error.to_string().contains("unknown field"));
}

#[test]
fn grouped_cache_round_trips_and_rejects_unsupported_runtime_modes() {
let wire = serde_json::json!({
"backend": "vllm",
"enable_prefix_caching": false,
"kv_cache_capacity_bytes": 1024,
"kv_cache_groups": [{
"name": "window", "kind": "attention", "num_layers": 4,
"block_size_tokens": 4, "page_size_bytes": 64, "sliding_window": 8
}]
});
let config: EngineConfig = serde_json::from_value(wire.clone()).unwrap();
config.validate().unwrap();
let reloaded: EngineConfig =
serde_json::from_value(serde_json::to_value(&config).unwrap()).unwrap();
assert_eq!(config, reloaded);
for (key, value, expected) in [
("backend", serde_json::json!("sglang"), "backend=vllm"),
(
"worker_type",
serde_json::json!("decode"),
"worker_type=aggregated",
),
(
"enable_prefix_caching",
serde_json::json!(true),
"enable_prefix_caching=false",
),
("aic_nextn", serde_json::json!(1), "speculative"),
("emit_kv_events", serde_json::json!(true), "KV event"),
(
"kv_cache_bytes_per_token",
serde_json::json!(64),
"linear cache",
),
(
"kv_cache_capacity_bytes",
serde_json::json!(0),
"positive kv_cache_capacity_bytes",
),
(
"native_host_offload",
serde_json::json!({"num_host_blocks": 1}),
"only HBM",
),
] {
let mut unsupported = wire.clone();
unsupported[key] = value;
let config: EngineConfig = serde_json::from_value(unsupported).unwrap();
let error = config.validate().unwrap_err();
assert!(error.to_string().contains(expected), "{key}: {error}");
}
let linear = serde_json::to_value(EngineConfig::default()).unwrap();
assert!(linear.get("kv_cache_groups").is_none());
assert!(linear.get("kv_cache_capacity_bytes").is_none());
}

#[test]
fn native_host_offload_deserializes_with_default_bandwidths() {
assert_eq!(DEFAULT_HOST_OFFLOAD_BANDWIDTH_GBPS, 32.0);
Expand Down
10 changes: 9 additions & 1 deletion crates/core/src/engine/kv_manager/g1_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use super::vllm_backend::{
StoreSourceSnapshot as VllmStoreSourceSnapshot, VllmAcquire, VllmKvManager,
};
pub(crate) use super::vllm_backend::{NativeAllocation, SourceReuseDependency};
use super::{AllocationRequirement, DestinationReservationMode, G1Acquire};
use super::{AllocationRequirement, DestinationReservationMode, G1Acquire, GroupedKvPool};

fn into_g1_acquire<T>(outcome: VllmAcquire<T>) -> G1Acquire<T> {
match outcome {
Expand Down Expand Up @@ -70,6 +70,14 @@ pub(crate) struct G1Manager {
}

impl G1Manager {
pub(crate) fn set_grouped_cache(&mut self, groups: GroupedKvPool) {
self.inner.set_grouped_cache(groups);
}

pub(crate) fn grouped(&self) -> Option<&GroupedKvPool> {
self.inner.grouped()
}

pub(crate) fn set_belady_oracle(&mut self, oracle: BeladyOracle) {
self.inner.set_belady_oracle(oracle);
}
Expand Down
Loading
Loading