A practical guide for choosing dimension override values when converting ONNX models to WebNN format.
- Understanding Dynamic Dimensions
- Inspection Methods
- Common Values by Model Type
- Decision-Making Process
- Troubleshooting
ONNX models often use symbolic dimensions (like batch_size, sequence_length) instead of fixed
numbers. This allows the same model to handle different input sizes.
Example ONNX input shape:
input_ids: [batch_size, sequence_length] # Dynamic
In many models, shape-driving expressions must become static for conversion:
input_ids: [1, 128] # Static
WebNN executes in browsers and edge devices where:
- Memory must be allocated upfront
- Shape-driving expressions (for example, reshape targets) must be resolvable
- Performance is optimized for specific sizes
webnn-graph can preserve unresolved symbolic input metadata in v2 graphs with
--experimental-dynamic-inputs, but conversion still needs concrete values when dynamic shape math
cannot be folded.
pip install onnxslim
onnxslim --inspect model.onnx- Install Netron:
pip install netron - Open model:
netron model.onnx - Click on input nodes to see shape information
- Look for dimension parameters like
batch_size,seq_len, etc.
Most models on Hugging Face include dimension information:
# Visit the model page
# https://huggingface.co/<org>/<model-name>
# Look for:
# - "Model Details" section
# - "max_seq_length" in config
# - Example usage codewebnn-graph supports automatic dimension discovery via .dims.json files:
# If model.onnx has a model.dims.json file, check it:
cat model.dims.jsonExample content:
{
"freeDimensionOverrides": {
"batch_size": 1,
"sequence_length": 128
}
}Typical dimensions:
--override-dim batch_size=1
--override-dim sequence_length=<128|256|512>Choosing sequence_length:
| Model Type | Recommended | Max | Use Case |
|---|---|---|---|
| Sentence embeddings (MiniLM, MPNet) | 128 | 256 | Sentences, titles, short text |
| Document classification (BERT) | 256 | 512 | Paragraphs, articles |
| Question answering (BERT, RoBERTa) | 384 | 512 | Q&A pairs with context |
| Text generation (GPT-2) | 512 | 1024 | Long-form generation |
| Long-document (Longformer) | 1024 | 4096 | Full documents |
How to determine:
# Check tokenizer max length
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("model-name")
print(f"Max length: {tokenizer.model_max_length}")Common dimension parameter names:
batch_size,batch,N,Bsequence_length,seq_len,max_len,T,Lhidden_size,hidden_dim(usually fixed, not dynamic)
Typical dimensions:
--override-dim batch_size=1
--override-dim height=224
--override-dim width=224Standard image sizes by architecture:
| Architecture | Size | Notes |
|---|---|---|
| ResNet-50/101 | 224×224 | ImageNet standard |
| EfficientNet-B0 | 224×224 | Scales up with variants |
| EfficientNet-B7 | 600×600 | Higher accuracy, slower |
| Vision Transformer (ViT-B) | 224×224 or 384×384 | Two common variants |
| MobileNet V2/V3 | 224×224 | Mobile-optimized |
| YOLO (object detection) | 416×416 or 640×640 | Detection-specific |
| Semantic segmentation | 512×512 or 1024×1024 | Full-resolution |
How to determine:
# Check preprocessing configuration
from transformers import AutoImageProcessor
processor = AutoImageProcessor.from_pretrained("model-name")
print(f"Size: {processor.size}")Common dimension parameter names:
batch_size,batch,N,Bheight,H,image_heightwidth,W,image_widthchannels,C(usually 3 for RGB, 1 for grayscale)
Typical dimensions:
--override-dim batch_size=1
--override-dim sequence_length=<varies> # Based on audio durationDetermining sequence_length for audio:
# Formula: sequence_length = sample_rate * duration_seconds / hop_length
# Example for Wav2Vec2 (16kHz, 10 seconds)
sample_rate = 16000
duration = 10 # seconds
hop_length = 320 # model-specific
sequence_length = (sample_rate * duration) // hop_length
# Result: ~500 for 10-second audioCommon values:
- Whisper: Processes 30-second chunks → sequence_length based on mel spectrogram frames
- Wav2Vec2: Variable based on audio duration
- Audio classification: Often 16000 samples (1 second at 16kHz)
Try converting without overrides first:
./webnn-graph convert-onnx --input model.onnxIf conversion cannot resolve required dims, error output will indicate what to set:
Error: unresolved dynamic dimension(s) require explicit overrides:
- input 'input_ids' dim 'batch_size': --override-dim batch_size=<value>
- input 'input_ids' dim 'sequence_length': --override-dim sequence_length=<value>
Look at the model filename or documentation:
*bert*,*roberta*,*gpt*→ Text model*resnet*,*efficientnet*,*vit*→ Vision model*wav2vec*,*whisper*→ Audio model
Always start with:
batch_size=1(single inference)- Smallest reasonable size for other dimensions
Why start small?
- Faster conversion and testing
- Less memory usage
- Easier to debug
- Can always increase later
Use the tables in Common Values by Model Type above.
# Test with initial values
./webnn-graph convert-onnx \
--input model.onnx \
--override-dim batch_size=1 \
--override-dim sequence_length=128
# If successful, test inference
# If shapes are wrong, adjust and retry# Model: sentence-transformers/all-MiniLM-L12-v2
# Task: Generate sentence embeddings
# 1. Check documentation
# Hugging Face says: max_seq_length = 256
# 2. Choose conservative value
# Most sentences < 128 tokens, so start there
# 3. Convert
./webnn-graph convert-onnx \
--input all-MiniLM-L12-v2.onnx \
--override-dim batch_size=1 \
--override-dim sequence_length=128 \
--optimize
# 4. If you need longer sequences, increase
./webnn-graph convert-onnx \
--input all-MiniLM-L12-v2.onnx \
--override-dim batch_size=1 \
--override-dim sequence_length=256 \
--optimize# Model: ResNet-50
# Task: Image classification
# 1. Standard size for ResNet is 224×224
# 2. No need to check - this is well-known
# 3. Convert
./webnn-graph convert-onnx \
--input resnet50.onnx \
--override-dim batch_size=1 \
--override-dim height=224 \
--override-dim width=224# 1. Inspect the model
python -c "
import onnx
model = onnx.load('custom_model.onnx')
for inp in model.graph.input:
print(inp.name, inp.type.tensor_type.shape)
"
# Output shows: data [N, 3, H, W]
# This is an image model (3 channels)
# 2. Try standard image sizes
./webnn-graph convert-onnx \
--input custom_model.onnx \
--override-dim N=1 \
--override-dim H=224 \
--override-dim W=224
# 3. If conversion fails, check error messages
# 4. Try other common sizes: 256, 299, 384, 512Solution: Some model paths still need concrete values for symbolic dimensions.
# Error shows which dimensions need values
Error: unresolved dynamic dimension(s) require explicit overrides:
- input 'input' dim 'height': --override-dim height=<value>
# Provide the missing dimensions
./webnn-graph convert-onnx \
--input model.onnx \
--override-dim height=224 \
--override-dim width=224Cause: The dimension values you provided are incompatible with the model's operations.
Solution:
- Check if the model has specific size requirements:
# Some models only work with specific sizes
# e.g., YOLO expects multiples of 32- Try multiples of common factors:
# For CNNs: try 224, 256, 288, 320, 384, 416, 512
# For transformers: try 128, 256, 384, 512- Enable optimization to help with shape inference:
./webnn-graph convert-onnx \
--input model.onnx \
--optimize \
--override-dim ...Cause: The model uses dynamic operations that can't be resolved with the given dimensions.
Solution:
- Make sure you've provided ALL dynamic dimensions:
# Check for missing dimensions
python -c "
import onnx
model = onnx.load('model.onnx')
for inp in model.graph.input:
for dim in inp.type.tensor_type.shape.dim:
if dim.dim_param:
print(f'Dynamic: {dim.dim_param}')
"- Use the
--optimizeflag:
./webnn-graph convert-onnx \
--input model.onnx \
--optimize \
--override-dim batch_size=1 \
--override-dim sequence_length=128Cause: The dimension values are too small for your actual input data.
Solution:
- Check your actual input size:
// In JavaScript
console.log("Input shape:", inputData.shape);- Increase dimensions to match:
# If your inputs are 256 tokens but you used 128
./webnn-graph convert-onnx \
--input model.onnx \
--override-dim sequence_length=256 # Increased from 128Cause: Dimension values are too large.
Solution:
- Reduce to smaller values:
# Instead of 512, try 256
# Instead of 256, try 128- Use batch_size=1 (not higher):
--override-dim batch_size=1 # Always use 1 for inferenceFor inference in WebNN (browsers/edge devices):
--override-dim batch_size=1Only increase batch size if you're doing batch processing server-side.
Choose dimensions based on your actual inputs:
- Short texts (tweets, titles):
sequence_length=128 - Medium texts (articles):
sequence_length=256 - Long texts (documents):
sequence_length=512+
Larger dimensions = more memory:
Memory ∝ batch_size × sequence_length × hidden_size
For browser inference, prefer smaller dimensions.
Standard sizes are well-tested:
- Images: 224, 256, 384, 512
- Text: 128, 256, 512, 1024
- These are powers of 2 or common multiples
Create a .dims.json file alongside your model:
{
"freeDimensionOverrides": {
"batch_size": 1,
"sequence_length": 128
},
"notes": "128 tokens handles 95% of our sentences. Max length is 256 if needed."
}After conversion, test with actual inputs:
// Verify converted model works with your data
const result = await context.compute(graph, {
input_ids: actualInputIds, // Your real input
attention_mask: actualMask
});--override-dim batch_size=1 --override-dim sequence_length=128--override-dim batch_size=1 --override-dim height=224 --override-dim width=224# 1. Try without overrides (see error message)
# 2. Check model documentation
# 3. Start with smallest reasonable values
# 4. Iterate based on errors/results- ONNX Model Zoo - Standard models with known shapes
- Hugging Face Model Hub - Model documentation
- Netron - Visual model inspector
- WebNN Specification - WebNN requirements
The decision process:
- Try converting without overrides and capture unresolved dimensions from the error
- Determine model type (text/vision/audio)
- Look up standard values for that model type
- Start with conservative (small) values
- Test and iterate as needed
Most common pattern:
./webnn-graph convert-onnx \
--input model.onnx \
--optimize \
--override-dim batch_size=1 \
--override-dim <other_dims>=<standard_value>Remember: batch_size=1 is almost always correct for inference!