Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
5f5ee9d
feat(metadata): declare how an encoder batches, and check that it can
Copilot Aug 24, 2026
717206d
feat(metadata): let a package declare how it preprocesses and packs v…
Copilot Aug 24, 2026
35b5303
feat(metadata): let a packing say which packing it sits inside
Copilot Aug 24, 2026
483cfc0
refactor(metadata): restate encoder batching on the design of record
Copilot Aug 24, 2026
e6889c4
feat(metadata): per-level packed extent and a real schema version gate
Copilot Aug 24, 2026
403fa07
fix(metadata): root budgets in the group, and stop emitting a new ver…
Copilot Aug 24, 2026
208e3f0
fix(metadata): scope the append-axis demand to the version that makes it
Copilot Aug 24, 2026
c3e37ab
docs(metadata): say which spelling is canonical, and pin it with tests
Copilot Aug 24, 2026
7da152f
test(metadata): pin the two rules the design adopted from this branch
Copilot Aug 24, 2026
8ac1eee
test(metadata): pin the delivery asymmetry between the three companions
Copilot Aug 24, 2026
92aac3f
feat(metadata): refuse the flat token_packed spelling with the migrat…
Copilot Aug 24, 2026
fd51d9d
fix(metadata): admit each serving companion at its own shape, not at …
Copilot Aug 24, 2026
45114e8
fix(metadata): a companion of a result nobody produces describes nothing
Copilot Aug 24, 2026
e4ee43f
docs(metadata): absence buys nothing for a field that was reshaped
Copilot Aug 24, 2026
068c6b5
docs(metadata): a retired spelling is not a version question
Copilot Aug 24, 2026
77d956f
test(metadata): a misshapen companion must not be sent to fix the wro…
Copilot Aug 25, 2026
b690c77
feat(metadata): a padded output has one account of how much of it is …
Copilot Aug 25, 2026
9151a37
test(metadata): the padding exclusion is keyed on padding, not on the…
Copilot Aug 25, 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: 5 additions & 1 deletion crates/onnx-genai-comfyui-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,11 @@ pub fn convert(
}
let document = lowering.build(adapters.as_ref().map(|(value, _)| value))?;

let metadata: InferenceMetadata = serde_json::from_value(document.clone())?;
// Through the shared entry point, not `serde` directly: a lowering that
// built its own document is exactly as capable of stamping a version it does
// not mean as a file on disk is.
let metadata: InferenceMetadata = onnx_genai_metadata::parse_metadata_json(&document)
.map_err(|error| ComfyUiConfigError::InvalidMetadata(error.to_string()))?;
onnx_genai_metadata::validate_metadata(&metadata)
.map_err(|errors| ComfyUiConfigError::InvalidMetadata(errors.join("; ")))?;

Expand Down
5 changes: 4 additions & 1 deletion crates/onnx-genai-comfyui-config/src/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,10 @@ impl<'a> Lowering<'a> {
workflow.insert("steps".to_owned(), Value::Array(steps));

let mut document = Map::new();
document.insert("schema_version".to_owned(), json!("v1"));
document.insert(
"schema_version".to_owned(),
json!(onnx_genai_metadata::SCHEMA_VERSION),
);
document.insert(
"pipeline".to_owned(),
json!({ "workflow": Value::Object(workflow) }),
Expand Down
2 changes: 1 addition & 1 deletion crates/onnx-genai-engine/src/bin/migrate_model_io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ fn migrate(
let rendered = format!("{HEADER}{}", serde_yaml::to_string(&document)?);
// Parse the result back through the real schema before writing. A tool that
// emits a package the runtime rejects is worse than no tool.
let parsed: onnx_genai_metadata::InferenceMetadata = serde_yaml::from_str(&rendered)?;
let parsed = onnx_genai_metadata::parse_metadata(&rendered, Some("yaml"))?;
onnx_genai_metadata::validation::validate_metadata(&parsed)
.map_err(|errors| format!("converted package does not validate: {errors:#?}"))?;
std::fs::write(&path, rendered)?;
Expand Down
1 change: 1 addition & 0 deletions crates/onnx-genai-engine/src/engine/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,7 @@ pub fn graph_port_contracts(
shape: None,
optional: false,
batch_layout: onnx_genai_metadata::BatchLayout::RequestAligned { axis: 0 },
padding: Vec::new(),
},
);
}
Expand Down
11 changes: 8 additions & 3 deletions crates/onnx-genai-engine/src/pipeline/generation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1123,9 +1123,14 @@ fn test_decoder_runtime_inner(shape: TestSessionShape) -> anyhow::Result<Workflo
// runtime behaviour over a document shape `validate_pipeline_spec`
// refuses. A fixture that cannot be loaded is a weak premise for a
// test about what happens once it is.
onnx_genai_metadata::validate_pipeline_spec(&onnx_genai_metadata::PipelineSpec {
workflow: workflow.clone(),
})
onnx_genai_metadata::validate_pipeline_spec(
&onnx_genai_metadata::PipelineSpec {
workflow: workflow.clone(),
},
// A workflow this crate builds today is a document written today, so
// it is held to everything the newest schema version asks for.
onnx_genai_metadata::SUPPORTED_SCHEMA_VERSION,
)
.map_err(|error| anyhow::anyhow!("the fixture package must validate: {error:?}"))?;
}
validate_generation_workflow(&workflow)?;
Expand Down
4 changes: 4 additions & 0 deletions crates/onnx-genai-engine/src/pipeline/islands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1157,6 +1157,7 @@ fn session_tensor_contract(
shape: Some(shape),
optional: false,
batch_layout: onnx_genai_metadata::BatchLayout::Shared,
padding: Vec::new(),
}
}

Expand Down Expand Up @@ -2369,6 +2370,7 @@ mod tests {
effects: Vec::new(),
row_scope: None,
cache_affects_state: Default::default(),
batch_capacity: None,
}
}

Expand All @@ -2386,6 +2388,7 @@ mod tests {
),
optional: false,
batch_layout: onnx_genai_metadata::BatchLayout::RequestAligned { axis: 0 },
padding: Vec::new(),
}
}

Expand All @@ -2396,6 +2399,7 @@ mod tests {
shape: Some(vec![onnx_genai_metadata::TensorDimension::Fixed(1)]),
optional: false,
batch_layout: onnx_genai_metadata::BatchLayout::Shared,
padding: Vec::new(),
}
}

Expand Down
5 changes: 4 additions & 1 deletion crates/onnx-genai-engine/src/pipeline/workflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5706,6 +5706,7 @@ mod workflow_sampling_binding_tests {
shape: None,
optional: false,
batch_layout: BatchLayout::default(),
padding: Vec::new(),
};

let value = workflow_request_value(&RuntimeInputRole::PromptTokens, &request, &contract)
Expand All @@ -5728,6 +5729,7 @@ mod workflow_sampling_binding_tests {
shape: None,
optional: false,
batch_layout: BatchLayout::default(),
padding: Vec::new(),
};

let error =
Expand All @@ -5750,6 +5752,7 @@ mod workflow_sampling_binding_tests {
shape: Some(vec![TensorDimension::Fixed(1)]),
optional: false,
batch_layout: BatchLayout::default(),
padding: Vec::new(),
};

let top_k = workflow_request_value(&RuntimeInputRole::SamplingTopK, &request, &contract)
Expand Down Expand Up @@ -5936,7 +5939,7 @@ pub(crate) struct WorkflowLoopPlan<'n> {
pub(crate) continue_when: &'n str,
pub(crate) max_iterations: &'n str,
pub(crate) termination: &'n onnx_genai_metadata::WorkflowLoopTermination,
pub(crate) iteration: &'n Option<onnx_genai_metadata::WorkflowLoopIteration>,
pub(crate) iteration: &'n Option<Box<onnx_genai_metadata::WorkflowLoopIteration>>,
pub(crate) carried: &'n [onnx_genai_metadata::WorkflowLoopCarry],
}

Expand Down
1 change: 1 addition & 0 deletions crates/onnx-genai-genai-config/src/compatibility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -849,6 +849,7 @@ fn port_contracts_from_graph(
shape: None,
optional: false,
batch_layout: onnx_genai_metadata::BatchLayout::RequestAligned { axis: 0 },
padding: Vec::new(),
},
)
})
Expand Down
16 changes: 14 additions & 2 deletions crates/onnx-genai-metadata/src/decoder_workflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,7 @@ pub fn decoder_workflow(
effects: Vec::new(),
row_scope: None,
cache_affects_state: BTreeSet::new(),
batch_capacity: None,
};

for (cell, port, contract, default) in [
Expand Down Expand Up @@ -429,6 +430,7 @@ pub fn decoder_workflow(
effects: Vec::new(),
row_scope: None,
cache_affects_state: BTreeSet::new(),
batch_capacity: None,
};

let mut body = vec![
Expand Down Expand Up @@ -558,10 +560,10 @@ pub fn decoder_workflow(
// special case.
termination: crate::schema::WorkflowLoopTermination::GenerationEos,
carried,
iteration: Some(crate::schema::WorkflowLoopIteration {
iteration: Some(Box::new(crate::schema::WorkflowLoopIteration {
value: LOOP_ITERATION.to_string(),
contract: scalar_contract(),
}),
})),
}],
};
Ok(spec)
Expand Down Expand Up @@ -682,6 +684,7 @@ pub fn iteration_variant(
},
),
cache_affects_state: decoder.cache_affects_state.clone(),
batch_capacity: None,
};

let component = policy.component().to_string();
Expand Down Expand Up @@ -977,6 +980,7 @@ impl Builder {
)]),
optional: false,
batch_layout: BatchLayout::Shared,
padding: Vec::new(),
},
role: SemanticInputRole::Runtime {
version: CONTRACT_VERSION.to_string(),
Expand Down Expand Up @@ -1401,6 +1405,7 @@ fn token_contract() -> TensorContract {
shape: dims(&["batch", "sequence"]),
optional: false,
batch_layout: request_aligned(),
padding: Vec::new(),
}
}

Expand All @@ -1411,6 +1416,7 @@ fn mask_contract() -> TensorContract {
shape: dims(&["batch", "kv_sequence"]),
optional: false,
batch_layout: request_aligned(),
padding: Vec::new(),
}
}

Expand All @@ -1421,6 +1427,7 @@ fn logits_contract() -> TensorContract {
shape: dims(&["batch", "sequence", "vocabulary"]),
optional: false,
batch_layout: request_aligned(),
padding: Vec::new(),
}
}

Expand All @@ -1431,6 +1438,7 @@ fn hidden_contract() -> TensorContract {
shape: dims(&["batch", "sequence", "hidden"]),
optional: false,
batch_layout: request_aligned(),
padding: Vec::new(),
}
}

Expand All @@ -1441,6 +1449,7 @@ fn state_contract() -> TensorContract {
shape: dims(&["batch", "kv_heads", "kv_sequence", "head_dim"]),
optional: false,
batch_layout: request_aligned(),
padding: Vec::new(),
}
}

Expand All @@ -1451,6 +1460,7 @@ fn lengths_contract() -> TensorContract {
shape: dims(&["batch"]),
optional: false,
batch_layout: request_aligned(),
padding: Vec::new(),
}
}

Expand All @@ -1461,6 +1471,7 @@ fn flag_contract() -> TensorContract {
shape: dims(&["batch"]),
optional: false,
batch_layout: request_aligned(),
padding: Vec::new(),
}
}

Expand All @@ -1471,6 +1482,7 @@ fn scalar_contract() -> TensorContract {
shape: Some(vec![crate::schema::TensorDimension::Fixed(1)]),
optional: false,
batch_layout: BatchLayout::Shared,
padding: Vec::new(),
}
}

Expand Down
20 changes: 16 additions & 4 deletions crates/onnx-genai-metadata/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,17 @@
//!
//! Implements the spec from <https://github.com/onnx/onnx/issues/8184>

/// Current inference-metadata schema version. Emitters should stamp this into
/// [`schema::InferenceMetadata::schema_version`]; readers treat an absent value
/// as this version.
/// The spelling of the base schema version that emitters stamp.
///
/// It stays `v1` because that is what every writer in this repository already
/// stamps and what 19 in-tree documents already say. Readers normalize the
/// spellings in the wild — absent, `v1`, `1`, `1.0` — onto
/// [`INITIAL_SCHEMA_VERSION`], so changing what is emitted would rewrite bytes
/// and semantic identities to say something no reader distinguishes.
///
/// A package that uses a field a later version introduced states that later
/// version instead, and must: see [`version`] and
/// [`BATCHING_SCHEMA_VERSION`].
pub const SCHEMA_VERSION: &str = "v1";

/// Built-in serialized capability identifiers.
Expand Down Expand Up @@ -108,6 +116,7 @@ pub mod parser;
pub mod schema;
pub mod session_state;
pub mod validation;
pub mod version;

pub use cache::{CacheDependencies, cache_dependencies};
pub use decoder_abi::decoder_abi;
Expand All @@ -121,7 +130,7 @@ pub use parser::{
MtpProposerSpec, SpeculatorConfigSource, SpeculatorDescriptor, SpeculatorProposerKind,
SpeculatorProposerStatus, detect_speculator, find_metadata_path, load_metadata,
load_metadata_from_dir, load_metadata_package, load_metadata_with_identity, load_pipeline_spec,
resolve_package_artifact,
parse_metadata, parse_metadata_json, resolve_package_artifact,
};
pub use schema::*;
pub use session_state::{
Expand All @@ -131,6 +140,9 @@ pub use validation::{
CapabilityReport, PipelineValidationError, RuntimeCapabilities, derived_capabilities, validate,
validate_metadata, validate_pipeline_spec, validate_structure_and_capabilities,
};
pub use version::{
BATCHING_SCHEMA_VERSION, INITIAL_SCHEMA_VERSION, SUPPORTED_SCHEMA_VERSION, SchemaVersion,
};

/// Generates the inference-metadata JSON Schema with deterministic object-key ordering.
pub fn inference_metadata_schema_json() -> Result<String, serde_json::Error> {
Expand Down
Loading
Loading