pipenetwork's picture
Add files using upload-large-folder tool
84e173b verified
Raw
History Blame Contribute Delete
3.05 kB
#!/usr/bin/env python3
"""
Run the MLX port of nvidia/Nemotron-Labs-TwoTower-30B-A3B (block-wise AR diffusion LM).
Example:
python run_twotower_mlx.py --model /path/to/weights \\
--prompt "The capital of France is" --max-new-tokens 64 \\
--block-size 16 --steps-per-block 16 --mask-token-id 3
`--model` must contain: the (MLX) safetensors + index, config.json, tokenizer files.
The custom modeling code (nemotron_twotower_mlx.py) must be importable.
"""
import argparse, glob, json, os, sys, time
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import mlx.core as mx
import mlx.nn as nn
from mlx_lm.models.nemotron_h import ModelArgs
from transformers import AutoTokenizer
from nemotron_twotower_mlx import TwoTowerModel, quantization_predicate
def load(model_path):
cfg = json.load(open(f"{model_path}/config.json"))
args = ModelArgs.from_dict(cfg)
model = TwoTowerModel(args)
# Quantized packages record {"group_size","bits","scheme"} in config; recreate
# the same quantized module structure BEFORE loading so scales/biases fit.
q = cfg.get("quantization")
if q:
pred = quantization_predicate(q["bits"], q["group_size"]) \
if q.get("scheme") == "mixed_v1" else None
nn.quantize(model, group_size=q["group_size"], bits=q["bits"],
class_predicate=pred)
weights = {}
for shard in sorted(glob.glob(f"{model_path}/*.safetensors")):
weights.update(mx.load(shard))
weights = model.sanitize(weights) # idempotent
model.load_weights(list(weights.items()), strict=True)
model.eval()
mx.eval(model.parameters())
tok = AutoTokenizer.from_pretrained(model_path)
return model, tok
def main():
p = argparse.ArgumentParser()
p.add_argument("--model", required=True)
p.add_argument("--prompt", default="The capital of France is")
p.add_argument("--max-new-tokens", type=int, default=64)
p.add_argument("--block-size", type=int, default=16)
p.add_argument("--steps-per-block", type=int, default=16)
p.add_argument("--mask-token-id", type=int, default=3)
p.add_argument("--confidence-threshold", type=float, default=0.9)
p.add_argument("--verbose", action="store_true")
a = p.parse_args()
t0 = time.time()
model, tok = load(a.model)
print(f"loaded in {time.time()-t0:.0f}s", file=sys.stderr)
ids = mx.array([tok(a.prompt)["input_ids"]])
eos = tok.eos_token_id
t0 = time.time()
out = model.generate_mask_diffusion(
ids, max_new_tokens=a.max_new_tokens, block_size=a.block_size,
steps_per_block=a.steps_per_block, mask_token_id=a.mask_token_id,
confidence_threshold=a.confidence_threshold, eos_token_id=eos,
verbose=a.verbose,
)
dt = time.time() - t0
gen = out[0].tolist()
n_new = len(gen) - ids.shape[1]
print(tok.decode(gen))
print(f"\n[{n_new} tokens, {model.last_nfe} denoiser evals, {dt:.1f}s, "
f"{n_new/dt:.1f} tok/s]", file=sys.stderr)
if __name__ == "__main__":
main()