Skip to main content

model-schema-validation

Use when defining model spec constraints, validating ExecuTorch model shapes, checking method signatures, or resolving dimension symbols.

Quellinformationen

Repository
software-mansion/react-native-executorch
Letzte Quellaktivität
5. September 2026 um 17:39
Erkannte Sprache von SKILL.md
Englisch
Sterne
1.758
Forks
97

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
model-schema-validation
description
Use when defining model spec constraints, validating ExecuTorch model shapes, checking method signatures, or resolving dimension symbols.
metadata
{"id":"model_schema_validation","scope":"src/core/schema.ts, src/extensions/*/tasks/*"}
# Skill: Model Schema Validation Guide Use this guide to define and enforce structural constraints (shapes, data types, runtime constraints) on loaded ExecuTorch `.pte` models using `validateSpec`. --- ## 🔍 Why Validate Model Specs? Every ExecuTorch model exposes a `schema` (`ModelSpec<ConcreteDim>`), derived either from standard ExecuTorch `MethodMeta` at load time or from an exported `get_model_schema` companion method returning a JSON model spec. To prevent runtime crashes, type mismatches, and memory allocation errors in C++, TypeScript task pipelines validate the loaded model's exported schema against allowed spec variants using `validateSpec` _before_ allocating static tensors or executing inference. --- ## 🛠️ Validation API Reference ```typescript import { validateSpec, method, f32, i64, i32, DynamicDim as Dyn, constraint, } from '../../../core/schema'; const { variant, dims } = validateSpec(model.schema, { batched: method( 'forward', [i64(1, Dyn('L')), i64(1, Dyn('L'))], [f32(1, 'D')], [ constraint.equality( { paramSide: 'input', tensorIdx: 0, dimIdx: 1 }, { paramSide: 'input', tensorIdx: 1, dimIdx: 1 } ), ] ), unbatched: method( 'forward', [i64(Dyn('L')), i64(Dyn('L'))], [f32('D')], [ constraint.equality( { paramSide: 'input', tensorIdx: 0, dimIdx: 0 }, { paramSide: 'input', tensorIdx: 1, dimIdx: 0 } ), ] ), }); const [D] = dims.constant('D'); const L = dims.range('L'); ``` ### Key Schema Utilities from `src/core/schema.ts`: - **`method(name, inputs, outputs, runtimeConstraints?)`**: Constructs a method specification. - **`f32(...)` / `i64(...)` / `i32(...)` / `ui8(...)`**: Shorthand helpers for tensor parameter specs. - **`StaticDim('symbol')` / String Literals**: Strings passed to shape helpers (e.g. `'H'`, `'W'`) automatically map to `StaticDim`, acting as **static dimension wildcards**. They bind strictly to `constant` positive integer dimensions in the exported spec. - **`DynamicDim('symbol')` (or `Dyn('symbol')`)**: Creates a dynamic dimension symbol. Must be used when a dimension genuinely varies at runtime and binds to a `range` or `enum` domain in the exported spec. - **Constraint Helpers (`constraint`)**: - **`DimRef` Object Literal (`{ paramSide: 'input' | 'output', tensorIdx, dimIdx }`)**: Explicit reference to a tensor's dimension. - **`constraint.equality(...dims)`**: Creates an equality constraint requiring the referenced dimensions to take the exact same value at runtime. - **`constraint.linear(lhs, rhs, a, b?)`**: Creates a linear constraint `lhs = a * rhs + b`. - **`validateSpec(exportedSchema, allowedVariants)`**: Compares the model's exported schema against named variants and returns `{ variant, dim, dims }`. - **Symbol Accessors (`dims` & `dim`)**: - `dims.constant('N', 'H')`: Extracts constant values for symbols as numbers. - `dims.range('S')`: Extracts range domains `{ min, max, step }`. - `dims.enum('E')`: Extracts enum choices `readonly number[]`. - `dims.dynamic('L')`: Extracts dynamic `range` or `enum` as raw `ConcreteDim`. - `dims.any('D')`: Extracts raw dimension value (`number`, `Range`, `readonly number[]`, or `ConcreteDim`). - `dim('N')`: Extracts value for a single symbol. --- ## 📏 Symbolic Dimensions & Dynamic Shapes Tensors can have static dimensions (integers), static symbol wildcards (strings), or dynamic symbols (`DynamicDim`). The `validateSpec` utility matches allowed variants in order: 1. **Numbers (Static Match)**: Must match the exact static integer in the exported spec. 2. **Strings / `StaticDim` (Static Wildcard Match)**: Binds string symbol names (e.g. `'H'`) to static constant integers in the exported spec. Repeated occurrences of the same static symbol must bind to the same constant value. 3. **`DynamicDim` (Dynamic Domain Match)**: Binds dynamic symbol names to `range` or `enum` domains in the exported spec. 4. **Variant Selection**: Specify multiple variant keys in `validateSpec` (e.g. `batched` vs `unbatched`). The validator tests variants sequentially and returns the first matching key and bound symbols. --- ## 🔀 Dimension Domains vs. Runtime Constraints Understanding the distinction between a dimension's **domain** and its **runtime value** is central to schema design and validation: ### 1. Dimension Domains & Domain Matching - **Dimension Domain**: The set of values a dimension may take: - `constant`: Exactly `value` (a singleton integer). - `range`: Any value between `min` and `max` stepping by `step`. - `enum`: Any value listed in `choices`. - **Runtime Value**: The concrete integer size of a tensor's dimension in a specific execution call. - **Domain Matching (`validateSpec`)**: - `validateSpec` performs static, load-time domain matching. - Dynamic symbols (`DynamicDim('S')`) bind to exported dimension domains. Reusing a symbol (`'S'`) across tensor inputs or outputs requires every occurrence to bind to the **exact same domain**. - ⚠️ **Key Rule**: Binding to the same domain does **NOT** mean runtime values coincide! Two dimensions bound to the same domain (e.g., both having range `1..512`) may take _different_ runtime values in a single execution (e.g. length 10 and length 25). ### 2. Runtime Constraints (`constraint.equality` & `constraint.linear`) - **Runtime Constraints**: Declarations about the **runtime values** of tensor dimensions during execution: - **Equality Constraint (`constraint.equality(...)`)**: Requires all referenced dimensions to take the exact same runtime value in any execution call. ```typescript method( 'forward', [f32('B', Dyn('S1')), f32('B', Dyn('S2'))], [f32('B', Dyn('S1'))], [ constraint.equality( { paramSide: 'input', tensorIdx: 0, dimIdx: 0 }, { paramSide: 'input', tensorIdx: 1, dimIdx: 0 } ), ] ); ``` - **Linear Constraint (`constraint.linear(...)`)**: Requires two dimensions to satisfy `dimLhs = a * dimRhs + b` at runtime. - **Validation & Enforcement**: - `validateSpec` verifies that the exported model spec declares the exact same runtime constraints (1-to-1 declaration match). - Native C++ validates input runtime constraints before invoking `model.execute()`. --- ## ⚙️ Companion JSON Spec (`get_model_schema`) For models with runtime dynamic dimensions or runtime constraints (equality/linear relations between dimensions), the `.pte` model exports a companion method named `get_model_schema` returning a JSON string representation of `ModelSpec<ConcreteDim>`. When `get_model_schema` is present, the C++ loader parses it to populate `model.schema` with exact `RangeDim` / `EnumDim` domains and runtime constraints. Without it, `model.schema` is populated strictly from static ExecuTorch `MethodMeta`. --- ## 📋 Common Validation Recipes ### 1. Classification (Batched vs Unbatched) Accepts an image tensor and outputs class probabilities: ```typescript const { variant, dims } = validateSpec(model.schema, { batched: method('forward', [f32(1, 3, 'H', 'W')], [f32(1, 'N')]), unbatched: method('forward', [f32(3, 'H', 'W')], [f32('N')]), }); const [N, H, W] = dims.constant('N', 'H', 'W'); const inpShape = { batched: [1, 3, H, W], unbatched: [3, H, W] }[variant]; const outShape = { batched: [1, N], unbatched: [N] }[variant]; ``` ### 2. Image-to-Image / Style Transfer Accepts an image tensor and returns a modified image tensor with identical dimensions: ```typescript const { dims } = validateSpec(model.schema, { default: method('forward', [f32(1, 3, 'H', 'W')], [f32(1, 3, 'H', 'W')]), }); const [H, W] = dims.constant('H', 'W'); ``` ### 3. Object Detection (Dynamic Box Count) Accepts an image tensor, and outputs boxes, scores, and class labels for `N` detections: ```typescript const { dims } = validateSpec(model.schema, { default: method('forward', [f32(1, 3, 'H', 'W')], [f32('N', 4), f32('N'), f32('N')]), }); const [N, H, W] = dims.constant('N', 'H', 'W'); ``` ### 4. Single-Model Pipeline (Fully Static Export) Assert exact shape constants from the task file: ```typescript const { dims } = validateSpec(model.schema, { default: method( 'denoise', [ f32(1, LATENT_CHANNELS, LATENT_SIZE, LATENT_SIZE), i64(1), f32(1, CLIP_MAX_TOKENS, CLIP_HIDDEN_SIZE), ], [f32(1, LATENT_CHANNELS, LATENT_SIZE, LATENT_SIZE)] ), }); ``` --- ## 🚫 Avoid / Anti-Patterns - **Do NOT write manual imperative shape/type checks:** Always use declarative `validateSpec` variants which report unified, readable mismatch errors. - **Do NOT use hardcoded integers for dynamic dimensions:** Use string symbols (like `'H'`, `'W'`, `'N'`) for dynamic dimensions. Conversely, fixed export dimensions should be integers. - **Do NOT skip validation at startup:** Validate `model.schema` before allocating static tensors. - **Do NOT skip validation for single-model pipelines:** Single-model pipelines should still validate against task shape constants. --- ## ⚠️ Failure Codes `validateSpec` and the native spec validation raise `SCHEMA_MISMATCH` (the spec-builder helpers `ConstantDim` / `RangeDim` / `EnumDim` raise `INVALID_ARGUMENT` for their own arguments). A runtime constraint violated by the tensors actually passed to `execute` raises `INVALID_ARGUMENT`, not `SCHEMA_MISMATCH`: the model is fine, the call is not. See the [Error Handling Skill](../error-handling/SKILL.md). --- ## 📋 Verification Checklist When specifying model schema validations, verify that: - [ ] Schema validation is performed immediately after model loading and before tensor initialization using `validateSpec(model.schema, { ... })`. - [ ] Dynamic dimensions are defined as string symbols, while fixed dimensions are plain integers. - [ ] Symbol values are extracted using `dims.constant(...)`, `dims.range(...)`, or `dims.enum(...)`. - [ ] Multiple shape variants (e.g. `batched` vs `unbatched`) are provided when supported. - [ ] Input and output constraints map accurately to model specifications. - [ ] New validation failures throw `SCHEMA_MISMATCH` (or `INVALID_ARGUMENT` when the caller's own arguments are at fault), never a bare `Error`.
Auf GitHub ansehen