Nanmur opened a new issue, #20007:
URL: https://github.com/apache/tvm/issues/20007

   ### Expected behavior
   
   Embedding `float32` parameter values as Relax constants, or binding 
equivalent values with `Function.bind_params`, should preserve the numerical 
result of a Relax function compiled for LLVM.
   
   Passing the same values as explicit VM arguments should be numerically 
equivalent to the embedded-constant form.
   
   ### Actual behavior
   
   On Windows, a pure Relax program produces an incorrect result when its 
weight and twelve broadcast bias vectors are embedded as `relax.const` values.
   
   The same program is correct when those values are passed as explicit VM 
arguments.
   
   For the minimal reproducer below, the embedded-constant path produces 
`-2.010380268096924`, while the NumPy reference is `-2.289207935333252`.
   
   The explicit-parameter path has a maximum absolute difference of `0` for the 
same input values.
   
   The minimal reproducer does not involve a model frontend.
   
   ### Environment
   
   - OS: Windows 11
   - Python: 3.11.14
   - TVM: 0.25.0 
   - Build: local Release build with LLVM `22.1.8`, target `llvm`
   - Device: CPU
   
   ### Steps to reproduce
   
   Save the following as `repro_relax_const.py` and run it with the Python 
environment that imports the matching TVM source and compiled libraries.
   
   ```python
   import numpy as np
   
   import tvm
   from tvm import relax
   from tvm.runtime import tensor as tvm_tensor
   
   
   def run(embed_as_constants):
       rng = np.random.default_rng(0)
       x_value = rng.normal(size=(1, 1)).astype("float32")
       weight_value = rng.normal(size=(1, 1)).astype("float32")
       bias_values = [rng.normal(size=(1,)).astype("float32") for _ in 
range(12)]
   
       expected = x_value @ weight_value
       for bias_value in bias_values:
           expected = expected + bias_value
   
       sinfo_x = relax.TensorStructInfo((1, 1), "float32")
       sinfo_w = relax.TensorStructInfo((1, 1), "float32")
       sinfo_b = relax.TensorStructInfo((1,), "float32")
       x = relax.Var("x", sinfo_x)
       weight = relax.Var("weight", sinfo_w)
       biases = [relax.Var(f"bias_{i}", sinfo_b) for i in range(12)]
   
       if embed_as_constants:
           weight_expr = relax.const(weight_value)
           bias_exprs = [relax.const(value) for value in bias_values]
           function_params = [x]
       else:
           weight_expr = weight
           bias_exprs = biases
           function_params = [x, weight, *biases]
   
       bb = relax.BlockBuilder()
       with bb.function("main", function_params):
           with bb.dataflow():
               result = bb.emit(relax.op.matmul(x, weight_expr))
               for bias_expr in bias_exprs:
                   result = bb.emit(relax.op.add(result, bias_expr))
               output = bb.emit_output(result)
           bb.emit_func_output(output)
       mod = bb.finalize()
   
       executable = relax.build(mod, target="llvm")
       vm = relax.VirtualMachine(executable, tvm.cpu(0))
       arguments = [tvm_tensor(x_value, tvm.cpu(0))]
       if not embed_as_constants:
           arguments.extend([tvm_tensor(weight_value, tvm.cpu(0))])
           arguments.extend(tvm_tensor(value, tvm.cpu(0)) for value in 
bias_values)
       actual = vm["main"](*arguments).numpy()
       print(f"embed_as_constants={embed_as_constants}")
       print("expected:", expected)
       print("actual:  ", actual)
       np.testing.assert_allclose(actual, expected, rtol=1e-5, atol=1e-5)
   
   
   run(False)  # Passes: maximum absolute difference is 0.
   run(True)   # Fails: maximum absolute difference is about 0.27882767.
   ```
   
   `run(False)` passes.
   
   `run(True)` fails with:
   
   ```text
   ACTUAL:  [[-2.0103803]]
   DESIRED: [[-2.289208]]
   Max absolute difference: 0.27882767
   ```
   
   I also reproduced the same parameter-mode distinction with an ONNX 
DenseNet-121 model on the same Windows environment.
   
   `from_onnx(..., keep_params_in_input=False)` produced a maximum absolute 
difference of `0.848955` against ONNX Runtime, while 
`keep_params_in_input=True` passed with a maximum absolute difference of 
`3.58e-06`.
   
   This ONNX result is supporting evidence only; the pure Relax script above is 
the intended minimal reproducer.
   
   ### Triage
   
   * needs-triage
   * type: bug


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to