import json
import os
import platform
from pathlib import Path
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
MODEL_REPO = "medmekk/Llama-3.2-1B-Instruct-bnb-nf4"
TOKENIZER_REPO = "meta-llama/Llama-3.2-1B"
TEST_PROMPTS = [
"The capital of France is",
"Two plus two equals",
"Once upon a time, there was a",
]
TOP_K = 10
def main() -> None:
os.environ.setdefault("CUBLAS_WORKSPACE_CONFIG", ":16:8")
torch.manual_seed(0)
import bitsandbytes as bnb
import transformers as hf_transformers
if not torch.cuda.is_available():
raise SystemExit("bitsandbytes 4-bit requires CUDA; no CUDA device found")
print(f"bitsandbytes-NF4 forward-pass reference for {MODEL_REPO}")
print(f" tokenizer from {TOKENIZER_REPO}")
print(
f" torch {torch.__version__}, transformers {hf_transformers.__version__}, "
f"bitsandbytes {bnb.__version__}"
)
print(f" platform {platform.platform()}")
print()
print("Loading NF4 model (via bitsandbytes, F32 compute) + base tokenizer ...")
tokenizer = AutoTokenizer.from_pretrained(TOKENIZER_REPO)
model = AutoModelForCausalLM.from_pretrained(
MODEL_REPO,
device_map="cuda",
dtype=torch.float32,
)
model.eval()
cfg = model.config
head_dim = getattr(cfg, "head_dim", None) or cfg.hidden_size // cfg.num_attention_heads
qc = getattr(cfg, "quantization_config", None)
quant_method = getattr(qc, "quant_method", None) if qc is not None else None
print(
f" hidden_size={cfg.hidden_size}, num_layers={cfg.num_hidden_layers}, "
f"vocab_size={cfg.vocab_size}, head_dim={head_dim}, quant_method={quant_method}"
)
print()
results: dict = {
"model_repo": MODEL_REPO,
"tokenizer_repo": TOKENIZER_REPO,
"methodology": "bitsandbytes-NF4 forward-pass oracle (transformers + bitsandbytes, "
"F32 compute on CUDA); validates candle-mi's anamnesis NF4 dequant load path",
"torch_version": torch.__version__,
"transformers_version": hf_transformers.__version__,
"bitsandbytes_version": bnb.__version__,
"platform": platform.platform(),
"model_type": cfg.model_type,
"quant_method": str(quant_method),
"hidden_size": cfg.hidden_size,
"num_layers": cfg.num_hidden_layers,
"vocab_size": cfg.vocab_size,
"head_dim": head_dim,
"test_cases": [],
}
with torch.no_grad():
for prompt in TEST_PROMPTS:
inputs = tokenizer(prompt, return_tensors="pt").to("cuda")
input_ids = inputs.input_ids
tokens = input_ids[0].tolist()
outputs = model(input_ids=input_ids, use_cache=False, return_dict=True)
last_logits = outputs.logits[0, -1, :].float().cpu()
top_vals, top_idx = last_logits.topk(TOP_K)
top_token_str = tokenizer.decode([int(top_idx[0])])
print(
f" prompt={prompt!r}: {len(tokens)} tokens, "
f"top1=({int(top_idx[0])}, {top_token_str!r}, {float(top_vals[0]):.4f})"
)
results["test_cases"].append(
{
"prompt": prompt,
"tokens": tokens,
"top_10": [
{"index": int(idx), "logit": float(val)}
for idx, val in zip(top_idx, top_vals, strict=False)
],
}
)
out_path = Path(__file__).parent / "bnb_nf4_forward_reference.json"
with open(out_path, "w") as f:
json.dump(results, f, indent=2)
n_cases = len(results["test_cases"])
file_size = out_path.stat().st_size
print(f"\nSaved {n_cases} test cases to {out_path} ({file_size / 1024:.1f} KB)")
if __name__ == "__main__":
main()