Instructions to use pipenetwork/Nemotron-Labs-TwoTower-30B-A3B-mlx-6bit with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- MLX
How to use pipenetwork/Nemotron-Labs-TwoTower-30B-A3B-mlx-6bit with MLX:
# Download the model from the Hub pip install huggingface_hub[hf_xet] huggingface-cli download --local-dir Nemotron-Labs-TwoTower-30B-A3B-mlx-6bit pipenetwork/Nemotron-Labs-TwoTower-30B-A3B-mlx-6bit
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- LM Studio
- Atomic Chat
| #!/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() | |