JANGQ-AI banner

Nemotron-3-Nano-Omni-30B-A3B-Reasoning Β· JANGTQ2

12.6 GB Β· ~85 tok/s decode on M4 Max Β· 30B / 3B-active hybrid Mamba-2 + Attention + MoE Β· native MLX, zero PyTorch in the hot path

Full multimodal (text + image + audio + video) port of NVIDIA's Nemotron-3-Nano-Omni-30B-A3B-Reasoning to Apple MLX, all four modalities running natively on Metal:

Modality Native MLX time vs PyTorch hybrid
Text <1s β€”
Image (1 tile, 512Γ—512) 1.4s 21Γ— faster
Audio (20s WAV transcribe) 2.1s 15Γ— faster
Video (8 frames analysis) 3.6s 17Γ— faster
LLM decode 85 tok/s identical (same tokens)

Bundle contents (single repo, everything included)

  • LLM β€” 52-layer hybrid Mamba-2 + Attention + MoE at JANGTQ2 quantization (TurboQuant 2-bit codec on routed experts)
  • Vision tower β€” NVIDIA RADIO ViT-Huge (32 blocks, 1280 hidden, 10 cls/register tokens) at fp16 β€” 1.31 GB
  • Vision projector (mlp1) β€” LayerNorm + Linear + GELU + Linear β†’ LLM hidden β€” 0.32 GB
  • Sound encoder β€” parakeet (24-layer Conformer, full Transformer-XL relative-position attention) at fp16 β€” 1.22 GB
  • Sound projector β€” RMSNorm + Linear + SquaredReLU + Linear β†’ LLM hidden β€” 0.03 GB
  • Source .py files β€” modeling.py, audio_model.py, image/video/audio processors (PyTorch fallback path)
  • Codec sidecar (jangtq_runtime.safetensors) β€” codebook + Hadamard signs (JANGTQ variants only)

Quantization recipe

Routed experts at 2-bit JANGTQ β€” most compressed variant. 4-entry centroid table per in_features. 8-bit affine on attention, shared experts, Mamba in/out_proj, embed, lm_head. Mamba 1-D + router gate fp16. Codec sidecar in bundle. Loads via jang_tools.load_jangtq. At 2-bit, the gather_tq Metal kernel reads 16 vals/u32 (vs 8 at 4-bit) for slightly higher decode tok/s than JANGTQ4.

All bundles in this family

Variant Size Tok/s Loader
MXFP4 (Osaurus) 22.6 GB ~113 mlx_lm.load
JANGTQ4 19.9 GB ~82 jang_tools.load_jangtq
JANGTQ2 12.6 GB ~85 jang_tools.load_jangtq

Install

pip install jang_tools mlx mlx_lm pillow soundfile scipy librosa imageio[ffmpeg]

(Optional, for the PyTorch hybrid fallback only: pip install transformers torch torchaudio timm open_clip_torch)

Native MLX multimodal (recommended β€” zero PyTorch dependency)

import mlx.core as mx
from jang_tools.nemotron_omni.model import NemotronHOmni

chat = NemotronHOmni("JANGQ-AI/Nemotron-3-Nano-Omni-30B-A3B-JANGTQ2", dtype=mx.float32)

# Text only
print(chat.turn("Capital of France?"))                                # "Paris."

# Image input β€” RADIO ViT runs natively in MLX on Metal (1.4s)
print(chat.turn("What's in this image?", images=["cat.jpg"]))

# Audio input β€” parakeet Conformer encoder native MLX (2.1s for 20s clip)
print(chat.turn("Transcribe what was said.", audio="speech.wav"))

# Video input β€” frame extraction + RADIO video_embedder + EVS pruning native MLX (3.6s for 8 frames)
print(chat.turn("Describe what happens.", video="clip.mp4",
                video_target_frames=8, video_apply_evs=True))

# Mixed modality
print(chat.turn(
    "Compare the image with the spoken description.",
    images=["scene.jpg"], audio="description.wav",
))

# Multi-turn β€” KV + Mamba state persists across turns
print(chat.turn("And what about the previous image?"))      # references prior turn
chat.reset()                                                  # new conversation

Reasoning ON / OFF

# Reasoning ON (default for Reasoning SKU): emits <think>...</think> + answer
chat.turn("Solve: 17 + 28 = ?", enable_thinking=True)

# Reasoning OFF: faster, more direct
chat.turn("Solve: 17 + 28 = ?", enable_thinking=False)

Text-only fast path (mlx_lm or load_jangtq)

For chat-only use cases, skip the multimodal load and use the LLM directly:

from mlx_lm import load, generate
model, tokenizer = load("JANGQ-AI/Nemotron-3-Nano-Omni-30B-A3B-JANGTQ2")
prompt = tokenizer.apply_chat_template(
    [{"role": "user", "content": "Capital of France?"}],
    tokenize=False, add_generation_prompt=True,
)
print(generate(model, tokenizer, prompt=prompt, max_tokens=20))   # "Paris."

(For JANGTQ4 / JANGTQ2: replace mlx_lm.load with from jang_tools.load_jangtq import load_jangtq_model. Vision/sound weights are silently dropped on the text-only path.)

Architecture (52 hybrid layers)

hybrid_override_pattern (52 chars):
"MEMEM*EMEMEM*EMEMEM*EMEMEM*EMEMEM*EMEMEMEM*EMEMEMEME"

   23 Γ— M = Mamba-2 SSM             (state-space, O(1) cache per token)
   23 Γ— E = MoE (128 routed Γ— 6)     (ReLUΒ² activation, no gate_proj)
    6 Γ— * = Attention                 (GQA 32q / 2kv heads, NO RoPE, head_dim=128)

Multimodal towers (fp16, native MLX):
   vision_model        β†’  RADIO ViT (NVIDIA C-RADIOv2-H)
   mlp1                β†’  LayerNorm + Linear + GELU + Linear β†’ llm_hidden
   sound_encoder       β†’  ParakeetEncoder (24 Conformer layers)
   sound_projection    β†’  RMSNorm + Linear + SquaredReLU + Linear β†’ llm_hidden

Cache (multi-turn):
   M layers  β†’  MambaCache (size=2: conv state + ssm state)  O(1)/token
   * layers  β†’  KVCacheSimple                                  O(L)/token
   E layers  β†’  stateless

Native context: 262 144 tokens (no RoPE extrapolation needed)

Special tokens

Token ID Purpose
<image> 18 Image / video patch placeholder (video reuses )
<so_embedding> 27 Audio frame placeholder
<img> ... </img> β€” Image/video region wrapper
<sound> ... </sound> β€” Audio region wrapper
`< im_end >`

Sampling guidance

Mode temperature top_p When
Greedy 0.0 β€” Deterministic; reasoning-correct
Recommended 0.6 0.95 DeepSeek-style sampler, balanced
Avoid 1.0 1.0 At 2-bit (JANGTQ2): flat logit + quant noise β†’ garbage tokens

Swift / vMLX support

Native Swift port is in vmlx-swift-lm under Libraries/MLXVLM/Models/NemotronHOmni/. The full multimodal pipeline (NemotronHOmni wrapper + RADIOVision + Parakeet + Projectors + image/audio/video preprocessors) compiles cleanly. Shared video utilities in Libraries/MLXVLM/VLMVideoUtils.swift are reused by Qwen 2/2.5/3/3.5/3.6 VL and Kimi VL for cross-VLM compatibility.

import MLXVLM

let frames = try await vlmExtractFramesUniform(url: videoURL, targetFrames: 32)
let pixels = vlmStackFramesIntoChannels(frames, imageSize: 512, temporalPatchDim: 2)
// β†’ MLXArray (n_groups, T*3=6, 512, 512) for RADIO video_embedder

License

NVIDIA Open Model License β€” see the base model for full terms. Quantization, conversion, native MLX port, and runtime by Jinho Jang (eric@jangq.ai).


πŸ¦– Osaurus is the open-source MLX inference server for Apple Silicon. πŸŒ€ JANG is the quantization + runtime stack powering this bundle.

Downloads last month

-

Downloads are not tracked for this model. How to track
MLX
Hardware compatibility
Log In to add your hardware

Quantized

Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Model tree for JANGQ-AI/Nemotron-3-Nano-Omni-30B-A3B-JANGTQ2

Finetuned
(42)
this model

Collection including JANGQ-AI/Nemotron-3-Nano-Omni-30B-A3B-JANGTQ2