Fix TransposeOptimizer type error on zero-point-less DequantizeLinear (#28716) (#29192)
### Problem
With `graph_optimization_level >= ORT_ENABLE_BASIC`, a model with mixed
int8/uint8 QDQ inside a local function fails session init:
```
Type Error: Type (tensor(int8)) of output arg (QuantizeLinear_out0) of node (QuantizeLinear) does not match expected type (tensor(uint8)).
```
### Root cause
The issue's "duplicate NodeArg name" title is a misdiagnosis —
`QuantizeLinear_out0` is created exactly once. The real cause: when
`TransposeOptimizer` pushes a Transpose through a `DequantizeLinear`
that has **no zero-point** (`MakeQDQNodeUnit`), it inserts a new
`QuantizeLinear` reusing the DQ's inputs. With no zero-point and no
`output_dtype`, ONNX type inference defaults the new Q's output to
**uint8**, but the value-info copied from the DQ input is **int8** →
`Graph::Resolve()` rejects it.
### Fix
In `MakeQDQNodeUnit`, when the DQ has no zero-point, set the inserted
Q's `output_dtype` to the DQ input's element type (ONNX domain only —
`output_dtype` exists from opset 21; the zero-point path is unchanged).
### Verification
Reporter's repro model:
```
ORT_DISABLE_ALL -> OK (before & after)
ORT_ENABLE_BASIC -> FAIL (before) -> OK (after)
```
- After the fix, the optimized model passes
`onnx.checker.check_model(full_check=True)`; the inserted node now
carries `output_dtype=int8`.
- Added regression test
`TransposeOptimizerTests.TestDequantizeLinearNoZeroPoint` (Transpose →
no-zp int8 DequantizeLinear → Transpose; expects the Transposes to
cancel).
### Scope
ONNX domain, opset 21+ (where `output_dtype` exists). Pre-21 and
`com.microsoft` QDQ rely on an explicit zero-point and are unaffected.
Fixes #28716