[Bug] [Relax] FLOAT16 quantize wraps positive INT16 saturation to -32768

オープン
#20,891 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
3/5
見積もり時間
1〜2日
初心者へのやさしさ
45/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
python
領域
compilers

調査の方向性

The payload names only the Relax relax.op.quantize call with float16 input and int16 output, plus the repro script. Run the snippet first to confirm the float16 path returns -32768 where the float32 path saturates to 32767. Then find where quantize's float-to-int16 clamp is lowered and check whether the clip bound is applied after float16 rounding. Done means both dtypes match the expected clipped output and the float32 assertion still passes.

索引モデルが issue の本文から書いたものです。

説明

needs-triage type: bug
Expected behavior

With scale 1 and zero point 0, quantizing finite positive values 65504 and 32768 to INT16 should saturate to 32767.

Actual behavior

Direct Relax execution returns:

FLOAT32: [32767, 32767, 32752, -32768]
FLOAT16: [-32768, -32768, 32752, -32768]

The inputs represent exactly the same finite values. The INT16 upper bound 32767 rounds up to 32768 in FLOAT16, so the final cast wraps instead of saturating. The FLOAT32 control matches the independent wide-domain clipping formula.

Environment

TVM 0.28.dev0 (local CPU build; build commit unavailable), LLVM 18.1.3, Python 3.12.3, NumPy 2.5.4, Linux x86_64.

Steps to reproduce

Run with python repro.py:

import numpy as np
import tvm
from tvm import relax

values = np.array([65504, 32768, 32752, -65504], dtype="float32")
expected = np.clip(np.rint(values.astype("float64")), -32768, 32767).astype("int16")
for dtype in ["float32", "float16"]:
    x = relax.Var("x", relax.TensorType((4,), dtype))
    builder = relax.BlockBuilder()
    with builder.function("main", params=[x]):
        result = builder.emit(relax.op.quantize(
            x, relax.const(1, dtype), relax.const(0, "int16"), axis=0, out_dtype="int16"))
        builder.emit_func_output(result)
    vm = relax.VirtualMachine(relax.build(builder.get(), target="llvm"), tvm.cpu())
    actual = vm["main"](tvm.runtime.tensor(values.astype(dtype))).numpy()
    print(dtype, "expected", expected.tolist(), "actual", actual.tolist())
    if dtype == "float32":
        np.testing.assert_array_equal(actual, expected)
Triage
  • needs-triage
主要言語
Python
スター
13.9k
フォーク
4k
平均マージ
8時間 6分
マージ済み PR(30日)
147

環境構築

このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

apache/tvm のほかの issue

apache/tvm の issue をすべて見る

似ている issue

Python の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。