Get Started with Nemotron 3.5 Lightning#
Nemotron 3.5 Lightning is a compact, text-only, reasoning-capable model in the Nemotron 3.5 Lightning family. It uses a hybrid Latent Mixture-of-Experts (LatentMoE) architecture that interleaves Mamba-2 and MoE layers with select attention layers, and it activates only 3B of its 30B total parameters per token, so it delivers strong reasoning and coding quality with the memory footprint and latency of a much smaller, dense model. The model also includes Multi-Token Prediction (MTP) layers, which provide native speculative decoding. The NIM exposes OpenAI-compatible and Anthropic-compatible APIs, so existing clients can use the same container for Chat Completions, Responses, Anthropic Messages, tool calling, and agentic workflows.
What NIM adds on top of direct vLLM. The runtime, quantization choices,
context length, GPU-memory allocation, parallelism, reasoning parser, and
tool-call parser are the same building blocks you would configure yourself
when running vLLM directly. The NIM’s contribution is the setup and
validation burden it removes: one model-specific container image, a tested
model/runtime combination, an
automatically selected packaged deployment profile
matched to the detected GPU, and a
per-precision support matrix that tells
you which profiles fit which GPUs before you start. You can still
override the packaged profile, tune memory, context length, and parallelism,
and pass raw vLLM flags through NIM_PASSTHROUGH_ARGS.
This page is the model-specific guide for Nemotron 3.5 Lightning. For the generic NIM LLM onboarding path, refer to Quickstart. For full endpoint examples, refer to API Reference. For tool calling and MCP integration, refer to Tool Calling and MCP Integration.
Known Issues#
This release includes the following known issues and limitations.
The following items are inherited from the vLLM backend or the model checkpoint configuration. You can use these items to configure and validate deployments.
Reasoning parser: Start the container with
--reasoning-parser nemotron_v3when you want vLLM to parse Nemotron 3 reasoning output. Without a reasoning parser, non-JSON responses can include<think>content in the assistantcontentfield, thereasoningfield can benull, and reasoning-token accounting can be reported as regular output tokens.Thinking budget: This model supports
thinking_token_budgetwhen thinking is enabled throughchat_template_kwargs: {"enable_thinking": true}.thinking_token_budgetlimits the thinking portion of generation, whilemax_tokensstill caps total generated tokens for the request. If a response ends before producing a final answer, increasemax_tokens, increasethinking_token_budget, or simplify the prompt.Responses token caps: For
/v1/responses,max_output_tokenscovers the total generated output budget. If the request spends the budget before producing final visible text, the response can returnstatus: "incomplete". Increasemax_output_tokensfor prompts that need more reasoning or longer final answers.JSON mode:
response_format: {"type": "json_object"}can suppress visible reasoning output and is recommended for structured responses that you validate with a schema.Tool calling: Requests that use
"tool_choice": "auto"require the container to start with--enable-auto-tool-choiceand--tool-call-parser qwen3_coder. Pass these usingNIM_PASSTHROUGH_ARGSin Docker, Kubernetes, or other orchestrated environments.BF16 multi-GPU startup on B200 and B300: On
NVIDIA-B200andNVIDIA-B300-SXM6-AC, a BF16 profile with a tensor-parallel size of 2 or more can fail during startup while the FlashInfer MoE kernels are being auto-tuned, with a CUDA illegal memory access raised fromflashinfer::trtllm_bf16_moe. This is an upstream FlashInfer defect in the auto-tuning sweep and is not an out-of-memory condition. It does not affect every deployment: it has been reproduced on driver595.58.03(R595), and the same container and profile start successfully on driver580.126.20(R580). If you encounter it, add--no-enable-flashinfer-autotunetoNIM_PASSTHROUGH_ARGS, or select a different MoE backend with--moe-backend triton. On Blackwell GPUs, an NVFP4 profile avoids this code path entirely. Refer to the Blackwell BF16 Multi-GPU Startup section.KV cache dtype: This model is calibrated for an FP8 KV cache, which is the NIM default. Do not set
--kv-cache-dtype nvfp4; NVFP4 KV cache is not recommended and can degrade multi-turn and reasoning quality. NVFP4 checkpoints automatically use an FP8 KV cache when--kv-cache-dtypeis left unset.Generation defaults: The model checkpoint can provide
generation_config.jsondefaults. Override sampling parameters per request when you need a different value. To ignore model-provided generation defaults and use vLLM defaults, add--generation-config vllmtoNIM_PASSTHROUGH_ARGS.Profile verification: Use the support matrix as the source of truth for supported GPU, precision, and TP combinations. After startup, verify the selected profile and served model with
/v1/metadata,/v1/models, and the startup logs.Backend validation errors: Some malformed requests, such as empty or missing
messages, are validated by the backend and can return backend error wording. Send a non-emptymessagesarray for Chat Completions and Anthropic Messages requests.Scope: Nemotron 3.5 Lightning is a text-only model. Use it for text reasoning, coding, tool calling, and agentic workflows. It is not a multimodal image, audio, or video model.
Prerequisites#
Before deploying a NIM LLM container, ensure your environment meets the following requirements:
Hardware Requirements#
The following are the minimum required specifications for supported hardware components:
Requirement |
Specification |
|---|---|
CPU |
AMD64, ARM64 |
GPU |
Refer to the Support Matrix |
Software Requirements#
Minimum required versions for supported software components.
Requirement |
Specification |
|---|---|
Operating System |
Ubuntu 22.04 LTS or later recommended |
Container Toolkit |
1.14.0 or later |
CUDA SDK |
12.9 or later |
GPU Driver |
580 or later |
Docker |
24.0 or later |
Operating System#
While other Linux distributions can be compatible with NIM, they have not been officially validated.
We recommend using Ubuntu 22.04 LTS or later for the best experience.
CUDA SDK#
Install CUDA SDK by following the CUDA installation guide for Linux.
GPU Drivers#
Install the NVIDIA GPU drivers by following the NVIDIA Driver Installation Guide.
Docker#
Docker is required to run the containerized NIM services.
Install Docker Engine for your Linux distribution by following the Docker Engine installation guide.
Verify that the Docker daemon is running and that your user can execute
dockercommands withoutsudo. Add your user to thedockergroup if needed:sudo groupadd docker sudo usermod -aG docker $USER
Log out and back in for the group change to take effect.
Container Toolkit#
The NVIDIA Container Toolkit enables Docker containers to access the host GPU.
Install the toolkit by following the NVIDIA Container Toolkit installation guide.
Configure Docker to use the NVIDIA runtime by following the Docker configuration steps.
Restart the Docker daemon after configuration:
sudo systemctl restart docker
NIM Container Access#
To download and deploy NIM containers, you need one of the following:
A free NVIDIA Developer Program membership.
An NVIDIA AI Enterprise license. To request a free 90-day evaluation license, refer to Ways to Get Started With NVIDIA AI Enterprise and Activate Your NVIDIA AI Enterprise License.
Generate Access Credentials#
An NGC Personal API key is not required to access most NVIDIA NIM containers and models hosted on NGC. An NGC API key is only required to download Production Branch (PB) models. This Get Started documentation uses a feature branch model as an example, so creating an NGC Personal API key is optional.
If you want to create an NGC Personal API key, do the following:
Generate the Personal API Key on the Setup API Keys page.
When creating the Personal API key, select at least NGC Catalog from the Services Included list. You can also include additional services if you want to use the same key for other purposes.
Warning
Legacy API keys are not supported by NIM. Always use a Personal API Key.
Verify NVIDIA Runtime Access#
To ensure that your setup is correct, run the following command:
docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi
This command should produce output similar to one of the following, where you can confirm CUDA driver version, and available GPUs.
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 580.95.05 Driver Version: 580.95.05 CUDA Version: 12.9 |
|-----------------------------------------+------------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+========================+======================|
| 0 NVIDIA H100 80GB HBM3 On | 00000000:1B:00.0 Off | 0 |
| N/A 36C P0 112W / 700W | 78489MiB / 81559MiB | 0% Default |
| | | Disabled |
+-----------------------------------------+------------------------+----------------------+
+-----------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=========================================================================================|
| No running processes found |
+-----------------------------------------------------------------------------------------+
Configuration#
Use environment variables to control authentication and model caching.
Export NGC API Key#
Note
An NGC API key is only required to download Production Branch (PB) models. You can skip this section if you did not create an NGC API key.
Export the variable in your shell (temporary), replacing
<VALUE>with your actual API key:export NGC_API_KEY=<VALUE>
Persist the variable (optional):
If using bash:
echo "export NGC_API_KEY=$NGC_API_KEY" >> ~/.bashrc
If using zsh:
echo "export NGC_API_KEY=$NGC_API_KEY" >> ~/.zshrc
Verify the variable is set:
echo "$NGC_API_KEY"
Model Cache#
NIM downloads model weights to a cache on the host that you mount into the container. Artifacts persist across restarts, so you do not pull the full model on every run.
Local Cache#
An essential variable to configure on your host system is the cache path directory. This directory is mapped from the host machine to container; assets (for example, model weights) are downloaded to this host directory and persist across container restarts. Configuring a local cache is highly recommended, as it avoids re-downloading large model files upon subsequent container restarts. You can name the environment variable containing the path to the local cache whatever you want.
Create the cache directory and export an environment variable:
export LOCAL_NIM_CACHE=~/.cache/nim
mkdir -p $LOCAL_NIM_CACHE
# Optionally add sticky bit to avoid issues writing to the cache if the container is running as a different user
chmod -R a+rwxt $LOCAL_NIM_CACHE
When you start the NIM container, you must map your host machine’s local cache directory ($LOCAL_NIM_CACHE) to the container’s internal cache path (/opt/nim/.cache) using a Docker volume mount, such as -v "$LOCAL_NIM_CACHE:/opt/nim/.cache". This mapping ensures that the large model weights downloaded by the container are saved to your host machine. Because containers are ephemeral, any data stored only inside the container is lost when it stops. By using a volume mount, subsequent container runs detect the existing model files in your local cache and skip the lengthy download process, allowing the NIM to start up faster.
Cache Directory Permissions#
The NIM container runs as a non-root user with GID 0 (root group). The cache directory on your host must be writable by GID 0:
sudo chgrp -R 0 "$LOCAL_NIM_CACHE"
sudo chmod -R g+rwX "$LOCAL_NIM_CACHE"
Run the container with the cache mounted:
docker run --gpus all \
-v "$LOCAL_NIM_CACHE:/opt/nim/.cache" \
...
To run as a custom user (e.g., your host user), pass -u <uid>:0:
docker run --gpus all -u $(id -u):0 \
-v "$LOCAL_NIM_CACHE:/opt/nim/.cache" \
...
Important
When using -u <uid>, you must include :0 to set GID 0 (e.g., -u $(id -u):0). The container’s writable directories are group-owned by GID 0. Without it, the container will fail with PermissionError when writing to cache, config, or log paths.
Tip
To make this setting permanent across terminal sessions, you can add export LOCAL_NIM_CACHE=~/.cache/nim to your ~/.bashrc or ~/.zshrc profile.
Installation#
Before running a NIM LLM container, you must authenticate with your deployment source, accept the governing terms, and pull the container image.
Docker Login#
If you created an NGC API key, authenticate with the NVIDIA Container Registry using the following command:
echo "$NGC_API_KEY" | docker login nvcr.io --username '$oauthtoken' --password-stdin
Use $oauthtoken as the username and NGC_API_KEY as the password. The $oauthtoken username is a special name that indicates that you will authenticate with an API key and not a user name and password.
Accept the Governing Terms#
Before you download a given NIM for the first time, you must accept the governing terms in the browser. Go to Nemotron 3.5 Lightning on NGC and click Accept Terms.
Pull the Container Image#
After you generate your API key and authenticate with your deployment source, download the NIM container image to your host machine.
Use the docker pull command to fetch the NIM container image.
docker pull nvcr.io/nim/nvidia/nemotron-3.5-lightning-30b-a3b:2.0.9-variant
Storage and Startup Notes#
Ensure the host has enough free disk space for the container image and the model cache. As a rough guide, the container image is on the order of tens of GB, and the model cache ranges from approximately 19 GB for an NVFP4 profile to approximately 63 GB for a BF16 profile, depending on precision and GPU configuration. Reserve additional space if you download multiple profiles or keep older container images on the same host.
The first launch downloads the model artifacts into the mounted cache directory, which can take some time depending on your hardware and network. Subsequent launches reuse the mounted cache and start faster.
Tip
By default, the model download produces little log output and can appear idle.
To follow the download progress, add -e NIM_LOG_LEVEL=INFO to the docker run
command.
To pre-populate the cache before serving traffic, first discover the profile
hash that matches your GPU and precision, then pass it to download-to-cache
with the --profile selector. Passing --profile avoids downloading the wrong
profile on hosts where profile auto-detection depends on runtime state.
List the available profiles for your hardware:
docker run --rm --gpus=all \ -e NGC_API_KEY=$NGC_API_KEY \ nvcr.io/nim/nvidia/nemotron-3.5-lightning-30b-a3b:2.0.9-variant \ list-model-profiles
Copy the profile hash from the row that matches your GPU, precision, and tensor-parallel size (for example, an NVFP4 or BF16 profile).
Export the profile hash and download it into the cache:
export NIM_MODEL_PROFILE="<profile-hash-from-step-1>" docker run --rm --gpus=all \ -e NGC_API_KEY \ -e NIM_MODEL_PROFILE \ -v "$LOCAL_NIM_CACHE:/opt/nim/.cache" \ nvcr.io/nim/nvidia/nemotron-3.5-lightning-30b-a3b:2.0.9-variant \ download-to-cache -p "$NIM_MODEL_PROFILE"
For details on discovering, selecting, and managing profiles, refer to Model Download.
Run NIM#
Run the container using your NGC API key to authenticate and download the model.
Nemotron 3.5 Lightning is a reasoning model, so launch it with the
nemotron_v3 reasoning parser enabled. Without the parser, the reasoning
trace and the final answer arrive together in choices[].message.content and
include a literal </think> marker, which most callers do not expect.
docker run --gpus=all \
-e NGC_API_KEY=$NGC_API_KEY \
-e NIM_PASSTHROUGH_ARGS="--reasoning-parser nemotron_v3" \
-e NIM_MODEL_NAME=nvidia/nemotron-3.5-lightning-30b-a3b \
-e NIM_SERVED_MODEL_NAME=nvidia/nemotron-3.5-lightning-30b-a3b \
-v "$LOCAL_NIM_CACHE:/opt/nim/.cache" \
-p 8000:8000 \
nvcr.io/nim/nvidia/nemotron-3.5-lightning-30b-a3b:2.0.9-variant
With the parser enabled, choices[].message.content contains only the final
answer, and any reasoning tokens are returned separately in
choices[].message.reasoning. The examples in the rest of this guide assume
this launch. If you launch without the parser, expect <think>...</think> in
content and adjust your client code accordingly.
Nemotron 3.5 Lightning runs on a single node. Most profiles start
successfully with default settings and do not require additional
NIM_PASSTHROUGH_ARGS beyond --reasoning-parser nemotron_v3. For
information about how NIM_PASSTHROUGH_ARGS is processed, refer to
Advanced Configuration.
Model Identifier#
Every request must send the served model identifier in the model field. The
launch command above sets it explicitly with NIM_SERVED_MODEL_NAME, so the
identifier matches the container name:
nvidia/nemotron-3.5-lightning-30b-a3b
Variable |
Purpose |
|---|---|
|
The identifier the server registers and reports through |
|
The model identity the NIM reports through its metadata endpoints. Keep it identical to |
You can choose any identifier that suits your deployment — set both variables to the same value and use it in every request. To confirm what a running server serves:
curl -s http://localhost:8000/v1/models | jq -r '.data[].id'
That value is the only one the model field accepts.
Note
These variables control only the identifier the service advertises. They do not change which weights are downloaded — those are resolved from the model manifest inside the image.
Setting them explicitly also keeps your deployment stable across releases: your clients continue to use the value you chose.
Recommended Runtime Settings#
The following settings cover profiles that need explicit runtime tuning beyond the standard launch command.
Per-Profile Passthrough Arguments#
Most profiles start successfully with default settings. On the following GPU and
precision combinations, set the recommended NIM_PASSTHROUGH_ARGS to avoid CUDA
out-of-memory (OOM) failures during startup or under load:
GPU |
TP |
PP |
Precision |
Recommended Arguments |
|---|---|---|---|---|
GB10 |
1 |
1 |
BF16 |
|
H100 |
1 |
1 |
BF16 |
|
On GB10 (DGX Spark), the BF16 profile shares the unified memory pool with the
host, so lowering --gpu-memory-utilization to 0.75 leaves memory headroom
and prevents OOM during startup. On H100 with a BF16 TP=1 profile, capping
--max-num-seqs at 512 bounds the KV-cache and activation memory and prevents
OOM under load. For additional ways to reduce per-GPU memory, refer to
Resolve Out-of-Memory Errors.
Pass the recommended arguments through the NIM_PASSTHROUGH_ARGS environment
variable when starting the container, appended to --reasoning-parser nemotron_v3 from the primary launch. For example, on GB10 with a BF16
profile:
docker run --gpus=all \
-e NGC_API_KEY=$NGC_API_KEY \
-e NIM_PASSTHROUGH_ARGS="--reasoning-parser nemotron_v3 --gpu-memory-utilization 0.75" \
-v "$LOCAL_NIM_CACHE:/opt/nim/.cache" \
-p 8000:8000 \
nvcr.io/nim/nvidia/nemotron-3.5-lightning-30b-a3b:2.0.9-variant
For an H100 with a BF16 TP=1 profile, use the following concurrency limit:
docker run --gpus=all \
-e NGC_API_KEY=$NGC_API_KEY \
-e NIM_PASSTHROUGH_ARGS="--reasoning-parser nemotron_v3 --max-num-seqs 512" \
-v "$LOCAL_NIM_CACHE:/opt/nim/.cache" \
-p 8000:8000 \
nvcr.io/nim/nvidia/nemotron-3.5-lightning-30b-a3b:2.0.9-variant
Note
Profiles not listed in this table do not require additional
NIM_PASSTHROUGH_ARGS to avoid out-of-memory failures. For a separate,
non-OOM startup issue that affects BF16 multi-GPU profiles on B200 and B300,
refer to Blackwell BF16 Multi-GPU Startup.
Blackwell BF16 Multi-GPU Startup#
On NVIDIA-B200 and NVIDIA-B300-SXM6-AC, a BF16 profile with a
tensor-parallel size of 2 or more can fail during startup while the FlashInfer
MoE kernels are being auto-tuned. The container exits before the server becomes
ready, and the logs end with a CUDA illegal memory access raised from
flashinfer::trtllm_bf16_moe:
torch.AcceleratorError: CUDA error: an illegal memory access was encountered
This is an upstream FlashInfer defect in the kernel auto-tuning sweep, not a configuration error, and it is not caused by insufficient memory. It does not occur on every deployment. In testing, two conditions had to coincide before the failure appeared:
Driver branch. The failure reproduces on driver
595.58.03(R595). The same container, GPU, and profile start successfully on driver580.126.20(R580).Serving options. The failure also requires a particular combination of serving options, such as a maximum model length of
24000together with--max-num-seqs 512. Either option on its own starts normally.
Because both conditions depend on how you deploy, treat the list above as the cases observed so far rather than an exhaustive one, and apply the workaround below whenever you encounter this failure.
If you encounter this failure, disable FlashInfer auto-tuning:
docker run --gpus=all \
-e NGC_API_KEY=$NGC_API_KEY \
-e NIM_PASSTHROUGH_ARGS="--reasoning-parser nemotron_v3 --no-enable-flashinfer-autotune" \
-v "$LOCAL_NIM_CACHE:/opt/nim/.cache" \
-p 8000:8000 \
nvcr.io/nim/nvidia/nemotron-3.5-lightning-30b-a3b:2.0.9-variant
The MoE kernels then run with their default tactics instead of auto-tuned ones, which can reduce throughput slightly but leaves accuracy unchanged. If startup still fails, select a different MoE backend instead:
export NIM_PASSTHROUGH_ARGS="--reasoning-parser nemotron_v3 --moe-backend triton"
On Blackwell GPUs, an NVFP4 profile avoids this code path altogether and is the preferred choice when BF16 is not a hard requirement.
Context Length#
Nemotron 3.5 Lightning natively supports a context window of
262,144 tokens (256K). This is the default --max-model-len and the value
reported by the /v1/models endpoint. No additional configuration is required
for context lengths up to 262,144 tokens.
To serve a context window larger than the native window, set the
VLLM_ALLOW_LONG_MAX_MODEL_LEN=1 environment variable and pass the desired
--max-model-len value in NIM_PASSTHROUGH_ARGS:
export VLLM_ALLOW_LONG_MAX_MODEL_LEN=1
export NIM_PASSTHROUGH_ARGS="--max-model-len 393216"
Note
A larger context window requires significantly more KV cache memory, which reduces the number of requests that can be served concurrently. Validate GPU memory headroom for your target hardware before serving production traffic. Context lengths beyond the native 262,144-token window extend the model past its configured positional encoding range, so validate output quality for your workload before relying on context lengths greater than 262,144 tokens.
Additional Settings for NVFP4 Checkpoints#
Nemotron 3.5 Lightning is calibrated for an FP8 KV cache, which is
the recommended setting and the NIM default. When running an NVFP4 checkpoint,
leave --kv-cache-dtype unset and the NVFP4 checkpoint automatically uses an
FP8 KV cache.
Note
Do not set --kv-cache-dtype nvfp4. This model is calibrated for an FP8 KV
cache. NVFP4 KV cache is not recommended: it has not been validated for
quality and can degrade multi-turn and reasoning quality. Only the KV-cache
storage dtype is affected; the model weights remain NVFP4.
Resolve Out-of-Memory Errors#
On lower-memory GPUs, the container can fail during startup or under load with a CUDA out-of-memory (OOM) error. The following options reduce the memory required per GPU, in order of preference:
Shard across more GPUs. Choose a profile with a higher tensor-parallel (TP) size so the model weights and KV cache are split across more devices—for example, a TP=4 or TP=8 profile instead of TP=1. Refer to the support matrix for the profiles available for Nemotron 3.5 Lightning.
Use a lower-precision profile. NVFP4 and W4A16 profiles use substantially less memory for model weights than BF16. On Blackwell GPUs, prefer an NVFP4 profile; on other GPUs, prefer a W4A16 profile.
Reduce the context window. A large
--max-model-lenreserves more KV cache. Lowering it below the native 262,144-token window frees memory:export NIM_PASSTHROUGH_ARGS="--max-model-len 131072"
Reduce concurrency. Lower
--max-num-seqs(the maximum number of concurrent sequences) and--max-num-batched-tokensto shrink the KV cache and activation memory:export NIM_PASSTHROUGH_ARGS="--max-num-seqs 32 --max-num-batched-tokens 8192"
Lower GPU memory utilization. If other processes share the GPU, reduce the fraction of GPU memory the NIM reserves so there is more headroom:
export NIM_PASSTHROUGH_ARGS="--gpu-memory-utilization 0.85"
You can combine these settings in a single NIM_PASSTHROUGH_ARGS string—for
example, --max-model-len 131072 --max-num-seqs 32. For information about how
NIM_PASSTHROUGH_ARGS is processed, refer to Advanced Configuration.
Interact with the API#
The NIM exposes OpenAI-compatible and Anthropic-compatible inference endpoints. The OpenAI-compatible endpoints are the following:
Chat Completions:
/v1/chat/completionsText Completions:
/v1/completionsResponses:
/v1/responses
The Anthropic-compatible endpoints are the following:
Messages:
/v1/messagesCount Tokens:
/v1/messages/count_tokens
Tip
Chat Completions, Text Completions, Responses, and Anthropic Messages support streaming.
Note
To carry context across turns, send the prior turns inline in the input array.
To enable server-side storage so that previous_response_id and response
retrieval work, start the container with VLLM_ENABLE_RESPONSES_API_STORE=1.
This increases memory usage.
Important
Reasoning and visible output share one max_tokens budget.
Nemotron 3.5 Lightning is a reasoning model. When thinking is enabled
(the default for the chat template), the tokens consumed by the reasoning trace
and the tokens consumed by the visible answer both count against max_tokens.
If the reasoning trace fills the budget first, the response returns with
finish_reason: "length" and no final answer.
Follow these rules in every example:
For concise or structured examples where you do not need reasoning, disable thinking by passing
chat_template_kwargs={"enable_thinking": false}in the request. This guarantees the entiremax_tokensbudget is available for the visible answer.For examples that explicitly demonstrate reasoning, size
max_tokenslarge enough for both the reasoning trace and the final answer, and either cap reasoning withthinking_token_budgeton/v1/chat/completionsor plan the budget explicitly.Verify that every request in your CI returns
finish_reason: "stop"and a non-empty final answer, notfinish_reason: "length".
Send a Chat Completion Request#
After the server is running, you can send a request to the chat completion endpoint:
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "nvidia/nemotron-3.5-lightning-30b-a3b",
"messages": [
{
"role": "user",
"content": "Hello! How are you?"
}
],
"max_tokens": 128,
"temperature": 0.0,
"chat_template_kwargs": {"enable_thinking": false}
}'
The chat_template_kwargs.enable_thinking: false flag disables reasoning for
this concise example so the full max_tokens budget is available for the
visible answer. Omit this flag to keep reasoning enabled, but size max_tokens
accordingly. Refer to the reasoning-budget note above.
The response has the following general format. The exact generated text can
vary by sampling settings and runtime configuration. Because the primary
launch enables --reasoning-parser nemotron_v3, the reasoning field
contains the parsed reasoning trace (or is null when the request disables
thinking, as this concise example does). If you launch without the parser,
the reasoning text and the </think> marker appear in content instead.
{
"id": "chatcmpl-87d0c4524fb6f1a4",
"object": "chat.completion",
"created": 1769635152,
"model": "nvidia/nemotron-3.5-lightning-30b-a3b",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Hello! I'm ready to help.",
"refusal": null,
"annotations": null,
"audio": null,
"function_call": null,
"tool_calls": [],
"reasoning": "..."
},
"logprobs": null,
"finish_reason": "stop",
"stop_reason": null,
"token_ids": null
}
],
"service_tier": null,
"system_fingerprint": null,
"usage": {
"prompt_tokens": 41,
"total_tokens": 46,
"completion_tokens": 5,
"prompt_tokens_details": null,
"completion_tokens_details": {
"reasoning_tokens": 2
}
},
"prompt_logprobs": null,
"prompt_token_ids": null,
"kv_transfer_params": null
}
Hold a Multi-Turn Conversation#
The Chat Completions endpoint is stateless. To carry context across turns,
resend the full conversation in the messages array, alternating user and
assistant turns after an optional system message:
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "nvidia/nemotron-3.5-lightning-30b-a3b",
"messages": [
{"role": "system", "content": "You are a concise assistant."},
{"role": "user", "content": "My favorite color is blue."},
{"role": "assistant", "content": "Noted — your favorite color is blue."},
{"role": "user", "content": "What did I just tell you?"}
],
"max_tokens": 128,
"temperature": 0.0
}'
Note
Append only the assistant content from prior turns to the history. When the
reasoning parser (--reasoning-parser nemotron_v3) is enabled, do not feed the
reasoning field back into messages.
Use the OpenAI Python SDK#
You can direct the OpenAI Python SDK at the NIM endpoint by setting
base_url to the local /v1 API path and providing any non-empty API key:
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8000/v1",
api_key="not-used",
)
response = client.chat.completions.create(
model="nvidia/nemotron-3.5-lightning-30b-a3b",
messages=[{"role": "user", "content": "Summarize GPU computing in one sentence."}],
max_tokens=128,
temperature=0.0,
extra_body={"chat_template_kwargs": {"enable_thinking": False}},
)
print(response.choices[0].message.content)
The extra_body={"chat_template_kwargs": {"enable_thinking": False}} argument
disables reasoning so the full max_tokens budget is available for the
one-sentence summary. Omit it when you want the model to reason before
answering, but raise max_tokens to leave room for both the reasoning trace
and the final answer.
For Anthropic Python SDK examples, refer to Messages (Anthropic-compatible).
Control Thinking Budget#
The primary launch above already enables the nemotron_v3 reasoning parser,
so parsed reasoning is available in choices[].message.reasoning. To use
thinking controls, enable thinking and set a thinking-token budget in the
request:
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "nvidia/nemotron-3.5-lightning-30b-a3b",
"messages": [
{
"role": "user",
"content": "I have a 3x3 grid of integers. Rows sum to 15, 18, 21. Columns sum to 12, 20, 22. Center is 7, top-left is 2. Find one valid grid."
}
],
"max_tokens": 4096,
"temperature": 0,
"seed": 42,
"chat_template_kwargs": {"enable_thinking": true},
"thinking_token_budget": 2048
}'
The thinking_token_budget value caps the reasoning portion of generation, and
max_tokens caps the combined total (reasoning + visible answer). Size the two
values so that the visible answer has room after reasoning:
max_tokens >= thinking_token_budget + expected_answer_tokens. In the example
above, max_tokens=4096 and thinking_token_budget=2048 leave up to 2048
tokens for the final grid answer even if reasoning uses its full budget.
When the reasoning parser is enabled, the response reports how many of the
generated tokens were reasoning tokens in
usage.completion_tokens_details.reasoning_tokens (completion_tokens remains
the combined total of reasoning tokens and content tokens). If a response
returns with finish_reason: "length" and an empty final answer, raise
max_tokens or lower thinking_token_budget and retry.
Note
thinking_token_budget is supported on the Chat Completions endpoint
(/v1/chat/completions). The Responses endpoint (/v1/responses) does not
enforce a thinking-token budget.
Enable Tool Calling and MCP Workflows#
The primary launch already sets --reasoning-parser nemotron_v3. To also
enable OpenAI-compatible tool calling, add the auto-tool-choice and
tool-call-parser flags to NIM_PASSTHROUGH_ARGS alongside the reasoning
parser:
export NIM_PASSTHROUGH_ARGS="--reasoning-parser nemotron_v3 --enable-auto-tool-choice --tool-call-parser qwen3_coder"
If you already use NIM_PASSTHROUGH_ARGS for profile-specific settings, append
these arguments to the same string. Both --enable-auto-tool-choice and
--tool-call-parser qwen3_coder are required when using "tool_choice": "auto".
The following request provides multiple tool choices and lets the model choose which one to call:
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "nvidia/nemotron-3.5-lightning-30b-a3b",
"messages": [
{
"role": "user",
"content": "What is the weather in Santa Clara, CA?"
}
],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather for a city.",
"parameters": {
"type": "object",
"properties": {
"location": {"type": "string"}
},
"required": ["location"]
}
}
},
{
"type": "function",
"function": {
"name": "search_docs",
"description": "Search internal documentation.",
"parameters": {
"type": "object",
"properties": {
"query": {"type": "string"}
},
"required": ["query"]
}
}
}
],
"tool_choice": "auto",
"max_tokens": 256
}'
A successful tool-calling response includes a tool_calls array under
choices[0].message. Your application executes the selected tool and sends the
tool result back to the model in a follow-up Chat Completions request.
For MCP, connect to MCP servers in your client application, convert the MCP
tool schemas to the OpenAI tools format, and pass them to
/v1/chat/completions. The NIM container does not connect to MCP servers
directly. For details and LangChain/LangGraph examples, refer to
Tool Calling and MCP Integration.
Structured JSON Output#
For structured-output use cases, request JSON mode through the
OpenAI-compatible response_format parameter and validate the response with
your preferred schema library, such as Pydantic:
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "nvidia/nemotron-3.5-lightning-30b-a3b",
"messages": [
{
"role": "user",
"content": "Return JSON with keys name and purpose for NVIDIA NIM."
}
],
"response_format": {"type": "json_object"},
"max_tokens": 128,
"temperature": 0.0,
"chat_template_kwargs": {"enable_thinking": false}
}'
For structured-output use cases, disable reasoning with
chat_template_kwargs.enable_thinking: false so the full max_tokens budget
produces the JSON payload rather than a reasoning trace followed by a truncated
JSON. If you leave reasoning enabled, raise max_tokens to accommodate both
the reasoning trace and the JSON output.
Frameworks that support OpenAI-compatible chat completions, such as
LangChain, LangGraph, LlamaIndex, Pipecat, OpenCode, and similar agent
frameworks, can use the local NIM endpoint by setting their base URL to
http://localhost:8000/v1 and using the served model name.
Verify Health Endpoints#
Verify that the NIM container is running by checking its health endpoints.
By default, these endpoints are served on port 8000. If you set
NIM_HEALTH_PORT, use that port instead.
Live Endpoint#
Check whether the server is running:
curl -v http://localhost:8000/v1/health/live
Example response:
GET /v1/health/live HTTP/1.1
Host: localhost:8000
User-Agent: curl/7.81.0
Accept: */*
HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Content-Type: application/json
Content-Length: 61
Connection: keep-alive
Cache-Control: no-store, no-cache, must-revalidate
{
"object": "health.response",
"message": "live",
"status": "live"
}
Ready Endpoint#
Check whether the model is fully loaded and ready for inference:
curl -v http://localhost:8000/v1/health/ready
Example response:
GET /v1/health/ready HTTP/1.1
Host: localhost:8000
User-Agent: curl/7.81.0
Accept: */*
HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Content-Type: application/json
Content-Length: 63
Connection: keep-alive
Cache-Control: no-store, no-cache, must-revalidate
{
"object": "health.response",
"message": "ready",
"status": "ready"
}
Streaming#
To receive responses incrementally as they are generated, enable streaming by
adding "stream": true to your request payload. Streaming is supported across
the /v1/chat/completions, /v1/completions, /v1/responses, and
/v1/messages endpoints.
When streaming is enabled, the API returns a sequence of Server-Sent Events (SSE).
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "nvidia/nemotron-3.5-lightning-30b-a3b",
"messages": [
{
"role": "user",
"content": "Write a short poem about a robot."
}
],
"max_tokens": 100,
"stream": true,
"chat_template_kwargs": {"enable_thinking": false}
}'
The chat_template_kwargs.enable_thinking: false flag disables reasoning
for this streaming example so the full max_tokens: 100 budget is spent
on the poem tokens. Without it, the model would consume the budget on the
reasoning trace first and the stream would end with finish_reason: "length" before producing visible poem text. Omit the flag to keep
reasoning enabled, but raise max_tokens to leave room for both the
reasoning trace and the final poem. Refer to the reasoning-budget note
earlier in this guide.
For Chat Completions and Text Completions, the response streams back in chunks.
Each chunk contains a data JSON object. These streams terminate with a
data: [DONE] message:
data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1694268190,"model":"nvidia/nemotron-3.5-lightning-30b-a3b","choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}],"prompt_token_ids":null}
data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1694268190,"model":"nvidia/nemotron-3.5-lightning-30b-a3b","choices":[{"index":0,"delta":{"content":"In"},"logprobs":null,"finish_reason":null,"token_ids":null}]}
data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1694268190,"model":"nvidia/nemotron-3.5-lightning-30b-a3b","choices":[{"index":0,"delta":{"content":" cir"},"logprobs":null,"finish_reason":null,"token_ids":null}]}
data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1694268190,"model":"nvidia/nemotron-3.5-lightning-30b-a3b","choices":[{"index":0,"delta":{"content":"cuits"},"logprobs":null,"finish_reason":null,"token_ids":null}]}
...
data: [DONE]
For the Responses API, stream events use typed SSE events such as
response.output_text.delta and terminate with response.completed. For
Anthropic-compatible Messages, stream events use Anthropic event names such as
content_block_delta and terminate with message_stop.