Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

Shared exponent is one too large when the block maximum is just below a power of two

Aperta Adatta ai principianti
#48 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
74/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
python, pytorch

Direzione di ricerca

Inizia da _shared_exponents in mx.mx_ops, raggiunto tramite la chiamata a _quantize_mx segnalata, e confronta il suo calcolo dell’esponente con l’approccio esatto di torch.frexp mostrato nell’issue. Aggiungi test di regressione per i casi vicini a 256 e a FLT_MAX, quindi verifica gli output attesi e i valori finiti con custom_cuda=False.

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

Descrizione

Hi, I found that _shared_exponents can choose an exponent one larger than floor(log2(max)), because torch.log2 is evaluated in float32 and rounds up to exactly k for a maximum just below 2^k. OCP MX's conversion algorithm (section 6.3) uses floor(log2(max)).

import numpy as np
import torch
from mx.mx_ops import _quantize_mx

def quantize(block, fmt):
    A = torch.tensor([block + [0.0] * (32 - len(block))], dtype=torch.float32)
    return _quantize_mx(A, 8, fmt, shared_exp_method="max", axes=[-1], block_size=32,
                        round="even", flush_fp32_subnorms=False, custom_cuda=False)[0].tolist()

m = float(np.nextafter(np.float32(256), np.float32(0)))  # 0x1.fffffep+7
print(torch.log2(torch.tensor(m)).item())  # 8.0
print(quantize([m, 2.0**-10], "fp8_e4m3")[:2])
# Actual: [256.0, 0.0]
# Expected: [224.0, 0.0009765625]

M = float(np.finfo(np.float32).max)
print(quantize([M, 1.0], "int8")[:2])      # Actual: [nan, nan]
print(quantize([M, 1.0], "fp8_e4m3")[:2])  # Actual: [inf, 0.0]

In the first block the scale is 2^0 instead of 2^-1, so 2^-10, which is exact at 2^-1, rounds to zero. Moving the maximum slightly away from 256 gives the expected [224.0, 0.0009765625]. Near FLT_MAX the exponent becomes 128: line 282 turns it into NaN, so a finite MXINT8 block becomes all NaN (44 of the 200 largest float32 values here), and for E4M3 the rescaling at line 292 overflows to inf instead of saturating to 448 * 2^119.

Reproduced on main at 7bc41952de394f5cc5e782baf132e7c7542eb4e4 with custom_cuda=False, Python 3.12.13 and PyTorch 2.13.0 on CPU.

Taking the exponent exactly fixes all three:

-    shared_exp = torch.floor(
-        torch.log2(
+    shared_exp = (torch.frexp(
             shared_exp + FP32_MIN_NORMAL * (shared_exp == 0).type(shared_exp.dtype)
-        )
-    )
+        ).exponent - 1).to(shared_exp.dtype)

With this change the three blocks give [224.0, 0.0009765625] and finite values, and the output on 8,000 random blocks per element format is unchanged. I found this while checking FloatLib, a Lean library for the OCP MX formats, and I'm happy to send a PR with regression tests.

Lingua principale
Python
Stelle
365
Fork
54
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Preparare l'ambiente

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 microsoft/microxcaling

Tutte le issue di microsoft/microxcaling

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.