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

Aperta
#20,891 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
3/5
Tempo stimato
1-2 giorni
Idoneità per principianti
45/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
python
Ambito
compilers

Direzione di ricerca

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.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

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
Lingua principale
Python
Stelle
13.9k
Fork
4k
Merge medio
8h 6m
PR unite (30g)
147

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di apache/tvm

Tutte le issue di apache/tvm

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.