torchnative
Guide가이드

Inference with real transformers진짜 transformers 로 추론하기

Stream tokens, choose a dtype knowingly, and quantise at load time.

토큰을 스트리밍하고, dtype 을 알고 고르고, 로드 시점에 양자화합니다.

Streaming tokens토큰 스트리밍

from threading import Thread
from transformers import TextIteratorStreamer

streamer = TextIteratorStreamer(tok, skip_prompt=True, skip_special_tokens=True)
inputs   = tok("On-device inference is", return_tensors="pt")
Thread(target=model.generate, kwargs=dict(**inputs, max_new_tokens=32, streamer=streamer)).start()

for piece in streamer:
    print(piece, end="", flush=True)

generate runs on a background thread while the main thread consumes the iterator. On an M-series desktop with SmolLM2-135M the first token arrived in 34 ms, then 47 tokens/s.

generate 는 백그라운드 스레드에서 돌고 메인 스레드가 이터레이터를 소비합니다. M 시리즈 데스크톱에서 SmolLM2-135M 의 첫 토큰은 34 ms, 이후 초당 47 토큰이었습니다.

float32 or bfloat16float32 인가 bfloat16 인가

In float32 the tokens match upstream's. Loaded in the checkpoint's native bfloat16 (the default when you pass no dtype) they can diverge. That is not a defect: upstream disagrees with itself on one prompt in three under an equivalent change of accumulation order.

float32 에서는 토큰이 upstream 과 같습니다. 체크포인트 고유의 bfloat16 (dtype 을 주지 않을 때의 기본값) 으로 읽으면 달라질 수 있습니다. 결함이 아닙니다: upstream 도 누적 순서를 동치로 바꾸면 세 프롬프트 중 하나에서 자기 자신과 어긋납니다.

Quantise while loading로드하면서 양자화

from torchnative.quant import TorchnativeConfig

model = AutoModelForCausalLM.from_pretrained(
    name, quantization_config=TorchnativeConfig("q8_0"))

Quantisation is module replacement, not a dtype: nn.Linear leaves are swapped for quantised ones before the weights land, so the dense model is never assembled. Formats: q8_0 (lossless on integer operands), q4_0, and the k-quant q4k, which needs layer widths divisible by 256. torchnative.quant.quantize_(model) does the same to a model already loaded.

양자화는 dtype 이 아니라 모듈 교체입니다: 가중치가 들어오기 전에 nn.Linear 잎을 양자화된 것으로 바꾸므로 밀집 모델이 조립되지 않습니다. 포맷은 q8_0(정수 연산자에 무손실), q4_0, 그리고 레이어 폭이 256 의 배수여야 하는 k-quant q4k. 이미 로드된 모델에는 torchnative.quant.quantize_(model) 가 같은 일을 합니다.

What refuses거부되는 것

torch.compile refuses by name, permanently: the stable ABI that lets one binary serve every CPython from 3.13 cannot coexist with the frame-evaluation hook it needs. Eager is the supported path.

torch.compile 은 영구적으로 이름으로 거부됩니다: 한 바이너리가 3.13 이후 모든 CPython 에서 돌게 하는 안정 ABI 가, 그것이 필요로 하는 프레임 평가 훅과 공존할 수 없습니다. 지원 경로는 eager 입니다.