원클릭으로
debugging-shape-inference
Guide for debugging shape inference errors, particularly "Inferred shape and existing shape differ" from ONNX C++.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Guide for debugging shape inference errors, particularly "Inferred shape and existing shape differ" from ONNX C++.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
| name | debugging-shape-inference |
| description | Guide for debugging shape inference errors, particularly "Inferred shape and existing shape differ" from ONNX C++. |
When onnx.shape_inference.infer_shapes(model, strict_mode=True) raises
ShapeInferenceError: Inferred shape and existing shape differ in dimension N,
the error does not include the node or value name. Use the following
workflow to locate the offending value.
import onnx
model = onnx.load("model.onnx")
try:
onnx.shape_inference.infer_shapes(model, data_prop=True, strict_mode=True)
except Exception as e:
print(e) # Note the dimension index and values, e.g. dim 0: (4) vs (5)
If the model infers cleanly without value_info, the bug is in one of those
annotations (not in the graph structure):
stripped = onnx.ModelProto()
stripped.CopyFrom(model)
del stripped.graph.value_info[:]
onnx.shape_inference.infer_shapes(stripped, data_prop=True, strict_mode=True)
# If this succeeds, the error is in value_info
vis = list(model.graph.value_info)
def test_with_vis(model, vis_to_keep):
m = onnx.ModelProto()
m.CopyFrom(model)
del m.graph.value_info[:]
for vi in vis_to_keep:
m.graph.value_info.append(vi)
try:
onnx.shape_inference.infer_shapes(m, data_prop=True, strict_mode=True)
return True
except:
return False
lo, hi = 0, len(vis)
while lo < hi:
mid = (lo + hi) // 2
if test_with_vis(model, vis[:mid + 1]):
lo = mid + 1
else:
hi = mid
bad_vi = vis[lo]
print(f"Problematic value: {bad_vi.name}")
For initializers, the actual tensor shape is ground truth:
for init in model.graph.initializer:
if init.name == bad_vi.name:
print(f"Initializer shape: {list(init.dims)}")
# Extract the annotated shape from value_info
dims = []
for d in bad_vi.type.tensor_type.shape.dim:
dims.append(d.dim_value if d.HasField("dim_value") else d.dim_param)
print(f"Annotated shape: {dims}")
For intermediate values, compare against what ONNX C++ infers from scratch:
stripped = onnx.ModelProto()
stripped.CopyFrom(model)
del stripped.graph.value_info[:]
inferred = onnx.shape_inference.infer_shapes(stripped, data_prop=True)
for vi in inferred.graph.value_info:
if vi.name == bad_vi.name:
# This is what ONNX C++ thinks the shape should be
print(vi)
| Symptom | Likely cause |
|---|---|
| Initializer shape != value_info shape | Bad annotation in the original model. Fix: correct shapes from the actual tensor at inference start. |
| Intermediate value has wrong concrete dim | Our op inference computed a wrong dimension. Fix: debug the specific op's infer_* function. |
| Symbolic dim where C++ infers concrete | Our inference was less precise but not wrong. Usually not an error in strict mode. |
The engine (_engine.py) corrects initializer shapes at the start of
_process_graph using the actual tensor as ground truth. This handles
malformed models where value_info annotations disagree with initializer
tensor shapes.