Text Generation
Transformers
Safetensors
English
nemotron_labs_audex
nvidia
nemotron-labs-audex
reasoning
general-purpose
SFT
audio-language-modeling
audio-understanding
text-to-speech
text-to-audio
speech-recognition
speech-translation
Instructions to use nvidia/Nemotron-Labs-Audex-2B with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use nvidia/Nemotron-Labs-Audex-2B with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="nvidia/Nemotron-Labs-Audex-2B")# Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("nvidia/Nemotron-Labs-Audex-2B", dtype="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use nvidia/Nemotron-Labs-Audex-2B with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "nvidia/Nemotron-Labs-Audex-2B" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "nvidia/Nemotron-Labs-Audex-2B", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/nvidia/Nemotron-Labs-Audex-2B
- SGLang
How to use nvidia/Nemotron-Labs-Audex-2B with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "nvidia/Nemotron-Labs-Audex-2B" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "nvidia/Nemotron-Labs-Audex-2B", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "nvidia/Nemotron-Labs-Audex-2B" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "nvidia/Nemotron-Labs-Audex-2B", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }' - Docker Model Runner
How to use nvidia/Nemotron-Labs-Audex-2B with Docker Model Runner:
docker model run hf.co/nvidia/Nemotron-Labs-Audex-2B
| # coding=utf-8 | |
| # Copyright (c) 2026, NVIDIA CORPORATION. All rights reserved. | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| from __future__ import annotations | |
| import json | |
| import math | |
| import os | |
| from pathlib import Path | |
| from typing import Iterable, Optional | |
| import numpy as np | |
| import torch | |
| SOUND_PLACEHOLDER = "<sound>" | |
| SOUND_TOKEN = "<so_embedding>" | |
| SOUND_START_TOKEN = "<so_start>" | |
| SOUND_END_TOKEN = "<so_end>" | |
| IM_END_TOKEN = "<|im_end|>" | |
| DEFAULT_SYSTEM_PROMPT = ( | |
| "<|im_start|>system\n" | |
| "You are a helpful and harmless assistant.\n\n" | |
| "You are not allowed to use any tools." | |
| "<|im_end|>\n" | |
| ) | |
| def strip_hf_prefix(path: str) -> str: | |
| """Convert Megatron-style hf:// paths into local filesystem paths.""" | |
| return path[len("hf://") :] if path.startswith("hf://") else path | |
| def load_audio(audio_path: str, target_sr: int = 16000) -> tuple[np.ndarray, int]: | |
| import librosa | |
| audio_data, sr = librosa.load(audio_path, sr=target_sr, mono=True) | |
| return normalize_audio(audio_data), sr | |
| def normalize_audio(audio: np.ndarray) -> np.ndarray: | |
| """Return mono float32 audio in [-1, 1], matching the Megatron eval path.""" | |
| audio = np.asarray(audio) | |
| if audio.ndim == 2: | |
| if audio.shape[1] <= 2: | |
| audio = audio.mean(axis=1) | |
| elif audio.shape[0] <= 2: | |
| audio = audio.mean(axis=0) | |
| else: | |
| raise ValueError(f"Unsupported audio shape: {audio.shape}") | |
| if audio.dtype == np.int16: | |
| audio = audio.astype(np.float32) / 32768.0 | |
| elif audio.dtype != np.float32: | |
| audio = audio.astype(np.float32) | |
| max_abs = float(np.abs(audio).max()) if audio.size else 0.0 | |
| if max_abs > 1.0: | |
| audio = audio / max_abs | |
| return audio.astype(np.float32, copy=False) | |
| def split_audio_into_clips( | |
| audio: np.ndarray, | |
| sample_rate: int = 16000, | |
| clip_duration: float = 30.0, | |
| ) -> list[np.ndarray]: | |
| """Split audio into fixed 30s clips; keep a padded final clip for Whisper.""" | |
| audio = normalize_audio(audio) | |
| clip_samples = int(round(sample_rate * clip_duration)) | |
| if clip_samples <= 0: | |
| raise ValueError(f"Invalid clip_samples: {clip_samples}") | |
| if audio.size == 0: | |
| audio = np.zeros(1, dtype=np.float32) | |
| num_clips = max(1, math.ceil(audio.shape[0] / clip_samples)) | |
| clips: list[np.ndarray] = [] | |
| for idx in range(num_clips): | |
| start = idx * clip_samples | |
| clip = audio[start : start + clip_samples] | |
| if clip.shape[0] < clip_samples: | |
| clip = np.pad(clip, (0, clip_samples - clip.shape[0])) | |
| clips.append(clip.astype(np.float32, copy=False)) | |
| return clips | |
| def extract_whisper_features( | |
| feature_extractor, | |
| audio: np.ndarray, | |
| sample_rate: int = 16000, | |
| clip_duration: float = 30.0, | |
| ) -> torch.Tensor: | |
| """Return NV-Whisper input features shaped (num_clips, 128, 3000).""" | |
| clips = split_audio_into_clips(audio, sample_rate=sample_rate, clip_duration=clip_duration) | |
| features = feature_extractor( | |
| clips, | |
| sampling_rate=sample_rate, | |
| return_tensors="pt", | |
| padding="max_length", | |
| return_attention_mask=False, | |
| ) | |
| input_features = features.input_features | |
| if input_features.ndim != 3: | |
| raise ValueError(f"Expected 3D Whisper features, got {tuple(input_features.shape)}") | |
| return input_features | |
| def parse_conversation(conversation: list[dict]) -> tuple[str, str]: | |
| human_prompt = "" | |
| gt_answer = "" | |
| for turn in conversation: | |
| if turn["from"] == "human": | |
| human_prompt = turn["value"].replace("<sound>\n", "").replace("<sound>", "").strip() | |
| elif turn["from"] == "gpt": | |
| gt_answer = turn["value"] | |
| return human_prompt, gt_answer | |
| def build_prompt_template( | |
| prompt: str, | |
| reasoning: bool = False, | |
| prompt_repitition: str = "none", | |
| ) -> str: | |
| if prompt_repitition not in {"none", "repetition"}: | |
| raise ValueError(f"Unknown prompt repetition mode: {prompt_repitition}") | |
| if prompt_repitition == "repetition": | |
| prompt = f"{prompt}\n{prompt}" | |
| if reasoning: | |
| return f"<|im_start|>user\n<sound>\n{prompt}<|im_end|>\n<|im_start|>assistant\n<think>\n" | |
| return f"<|im_start|>user\n<sound>\n{prompt}<|im_end|>\n<|im_start|>assistant\n<think></think>" | |
| def expand_sound_placeholder(prompt: str, num_embeddings: int) -> str: | |
| if prompt.count(SOUND_PLACEHOLDER) != 1: | |
| raise ValueError(f"Expected exactly one {SOUND_PLACEHOLDER}, found {prompt.count(SOUND_PLACEHOLDER)}") | |
| replacement = SOUND_START_TOKEN + (SOUND_TOKEN * num_embeddings) + SOUND_END_TOKEN | |
| return prompt.replace(SOUND_PLACEHOLDER, replacement) | |
| def build_attention_mask(input_ids: torch.Tensor) -> torch.Tensor: | |
| return torch.ones_like(input_ids, dtype=torch.long) | |
| def split_thinking(response: str) -> tuple[str, str]: | |
| if "</think>" not in response: | |
| return "", response.strip() | |
| thinking = response.rsplit("</think>", 1)[0].strip() + "</think>" | |
| prediction = response.rsplit("</think>", 1)[1].strip() | |
| return thinking, prediction | |
| def save_results_jsonl(results: Iterable[dict], output_path: str) -> None: | |
| os.makedirs(os.path.dirname(output_path) or ".", exist_ok=True) | |
| with open(output_path, "w", encoding="utf-8") as f: | |
| for result in results: | |
| f.write(json.dumps(result, ensure_ascii=False) + "\n") | |
| def resolve_audio_preprocessor_path(model_path: str, config) -> str: | |
| path = getattr(config, "audio_preprocessor_path", None) or "audio_preprocessor" | |
| candidate = Path(path) | |
| if not candidate.is_absolute(): | |
| candidate = Path(model_path) / candidate | |
| return str(candidate) | |