~/satyajit

PhoneLLM Alpha 1: the fine-tune is free, the cost line isn't

mdjsonmcp

2026-08-28 · 13 min · voice-agents · mixture-of-experts · fine-tuning · benchmarks · inference · nemotron

Pipecat's phonellm-alpha-1 model card reads like a paper — a leaderboard, a latency budget, a cost estimator, an ablation-style before/after comparison — and it invites the same treatment a paper gets here: pull the primary sources apart and see what's actually load-bearing. There's no arXiv id attached to this one. The primary sources are the Hugging Face repo itself: config.json, the safetensors headers of thirteen shards, the six chart images the card embeds, and a linked Google Sheet that turned out to still be live and publicly readable.

The headline claim is straightforward — a full-parameter fine-tune of NVIDIA's Nemotron 3 Nano 30B-A3B, tuned specifically for phone-agent tool use, scoring "on par with GPT 5.6 Terra, but 94% cheaper and with 1,300ms faster P95 time-to-first-token" on a new benchmark the same team built, PhoneBench v1. Company benchmark, company model, company blog post — the discipline here isn't "assume it's wrong," it's "check what's checkable." Most of it is, and most of it holds up better than the median vendor claim on this site. One sentence in the middle of the cost section does not.

ModelPhoneLLM Alpha 1 (pipecat-ai/phonellm-alpha-1) — Daily / Pipecat
BaseNVIDIA Nemotron 3 Nano 30B-A3B — hybrid Mamba-Transformer MoE, 52 layers: 23 Mamba2, 6 full attention, 23 MoE-FFN
TrainingFull-parameter supervised fine-tuning, NVIDIA NeMo, on production agent traces
Params31.578B total, 3.580B active per token — computed from the safetensors headers, matches the card's "30B / 3.5B" to three significant figures
Context262,144 tokens
BenchmarkPhoneBench v1 — LLM-judge panel over 15 models, scored on accuracy, speaking style, tool-call say/do consistency, TTFAT, and cost/min
Headline result72.3% score (GPT-5.6 Terra: 72.4%) at $0.0025/min and 331ms P50 TTFAT (Terra: $0.0347/min, 980ms)
Checked and holdingthe 3.580B active-param math; the 1,293ms latency-budget sum; the base-vs-tuned identical-cost claim (they share an architecture, so they share a cost row)
Checked and not holdingthe worked cost-per-minute example (states $0.00025/min; the arithmetic, the card's own spreadsheet, and the card's own leaderboard chart all say $0.0025); "94% cheaper" (the leaderboard's own two numbers give ~92.8%)

The 3.5B active checks out, tensor for tensor

config.json names the architecture: NemotronHForCausalLM, n_routed_experts: 128, num_experts_per_tok: 6, n_shared_experts: 1. The hybrid_override_pattern string — 52 characters, one per layer — spells out which of three block types each layer uses: Mamba2 mixer, full self-attention, or an MoE feed-forward block. Neither Mamba nor attention layers here carry a separate MLP; capacity comes entirely from the 23 layers typed E. Pulling the header of all 13 model-*.safetensors shards via HTTP range requests (the first 8 bytes give a header length, the next N bytes are a JSON manifest of every tensor's shape and dtype — no need to download 62GB of actual weights) gives the real split:

Summing every tensor's element count gives 31,577,940,288 total parameters — 31.578B, against the header's own declared metadata of 31,577,937,344 (the ~3,000-element gap is rounding in a couple of F32 buffers, not a discrepancy worth chasing). Of that, 29.375B (93.0%) sits in the 128×23 routed-expert bank. Active parameters — everything always-on, plus 6/128 of the routed-expert mass — comes to:

dense (Mamba + attention + embed/lm_head/norms):  1,736,234,432
shared experts (always active, all 23 layers):       458,981,376
router gates (always active, all 23 layers):            7,916,416
routed experts, 6-of-128 active fraction:           1,376,944,128
                                                    ---------------
active total:                                       3,580,076,352

3.580B active, 31.578B total — the card's "30B total, 3.5B active" isn't rounded generously, it's accurate to the third significant figure. That's worth stating plainly, because the more interesting finding in this model card isn't a number that's wrong — it's what a correct number implies once you compare it against a model this is a fine-tune of.

The whole gain is the fine-tune, not the architecture

PhoneLLM is a full-parameter fine-tune — no adapter files, no LoRA config, no quantization markers in the repo, just a standard 13-shard bfloat16 checkpoint with the identical config.json as the base model. That single fact makes a specific comparison possible: the base model, NVIDIA-Nemotron-3-Nano-30B-A3B, appears in PhoneBench's own leaderboard as a scored row, under the same hardware, same serving stack, same everything except the weights.

PhoneBench v1, 15 models, real chart values
modelscoreTTFAT P50P95cost/min
Gemini 3.6 Flash78.6%11681468$0.0751
GPT-5.6 Terra72.4%9801957$0.0347
PhoneLLM Alpha 172.3%331 (197 floor)~600$0.0025
GPT-5.6 Luna70.7%7861736$0.0035
Qwen 3.8 27B70.0%-- (286 floor)--$0.0074
Claude Sonnet 568.9%16512166$0.0520
DeepSeek V4 Flash 073168.6%464 (303 floor)~600$0.0687
Claude Haiku 4.567.8%707899$0.0188
Gemma 4 31B58.1%385 (254 floor)~600$0.0101
Kimi K2.6 NVFP457.9%313 (227 floor)~600$0.0372
Gemini 3.5 Flash Lite57.8%11901339$0.0082
GPT-4.157.4%8891190$0.0292
Nemotron 3 Super 120B base55.9%274 (235 floor)~600$0.0036
Nemotron 3 Ultra 550B-A55B base38.1%342 (240 floor)~600$0.0279
Nemotron 3 Nano 30B base28.6%331 (197 floor)~600$0.0025

Sort by TTFAT or cost and PhoneLLM Alpha 1 and Nemotron 3 Nano 30B base land on the exact same row — 331ms / 197ms floor / ~600ms P95, $0.0025/min, digit for digit. That’s not a coincidence, it’s the same weight shapes on the same hardware: full-parameter fine-tuning changes what the model outputs, not how much compute producing that output costs. Sort by score and the only thing that moved is 72.3% against 28.6% — 43.7 points, for free, on an unchanged latency and cost profile.

Sort that table by latency or cost and PhoneLLM Alpha 1 and Nemotron 3 Nano 30B base land on the identical row: 331ms P50 TTFAT, 197ms floor, ~600ms P95, $0.0025/min — not close, identical to four decimal places. That has to be true if the fine-tune changed weights and nothing else (same tensor shapes, same MoE routing cost, same everything the GPU has to compute), and it's a clean, free sanity check that the benchmark's own latency and cost measurements are internally consistent rather than noise. What moved is the score: 28.6% for the untuned base, 72.3% for PhoneLLM — a 43.7-point jump, on a benchmark scoring tool-call accuracy and phone-agent speaking style, for the price of a training run that changed nothing about inference cost or speed. That's the actual headline result buried under the GPT-5.6 Terra comparison: full-parameter SFT bought PhoneLLM parity with a much larger frontier model's phone-agent behavior, without moving a single number on the latency/cost side of the ledger.

The before/after, in the model's own words

The card's qualitative example is a real transcript excerpt, not a synthesized illustration, and PhoneBench's judging methodology explains exactly what it's scoring when it looks at a turn like this one.

Two PhoneBench judging examples. Example 1: two candidate greetings, one generic and one including the business name; the judges note the business-name candidate wins. Example 2: two candidate responses to a vehicle lookup request, one that calls lookup_vehicle_records and one that asks the caller for the VIN with no tool call; the judges note the tool-calling candidate saves the caller time.
How a turn gets scored: an LLM-judge panel comparing two candidate responses to the same caller turn, with the tool call itself as visible evidence (PhoneLLM Alpha 1 model card, image 03).

Both examples score a specific, checkable behavior rather than a vague notion of "quality" — whether the greeting names the business, whether a response that claims to look something up actually calls a tool to do it. That's the exact axis the model card's own before/after example is built around:

restaurant booking call, same two turns, verbatim
caller: “Yes, 7pm please
NEMOTRON 3 NANO 30B (base)

Thank you, David. I'll go ahead and book a table for 5 at 7:00 PM tonight. To complete the reservation, could you please let me know if you have any special requests (e.g., high chair, accessibility needs, celebration)?

no tool call — nothing was booked
PHONELLM 30B ALPHA 1

Great, let me book that for you.

create_reservation(caller_name: "David Smith", phone_number: "01253 172832", party_size: 5, date: "2026-08-24", time: "7:00 PM")

Your table is confirmed for tonight at 7:00 PM. Your confirmation code is R1007. Is there anything else I can help you with?

Same weights count, same architecture, same latency profile — the only difference between these two columns is the fine-tune. The base model narrates a plausible-sounding action (“I’ll go ahead and book a table”) without ever calling create_reservation, and on turn 2 ends the call without calling close_guest_call — a real reservation that never exists and a call state that never closes. PhoneBench’s judge panel scores exactly this gap — say/do consistency — and it is the specific failure mode the card says thinking-disabled models fall into most: “LLMs will often say ‘Yes, I’ve booked that table for you’ without actually doing it.”

Side-by-side transcript comparison. Nemotron 3 Nano 30B (base) responds to a caller's booking confirmation with a polite follow-up question and no tool call, then later ends the call with no tool call, leaving the reservation unbooked. PhoneLLM 30B Alpha 1 responds to the same two turns by calling create_reservation and then close_guest_call, with a confirmation code shown to the caller.
The exact transcript the model card ships as its before/after example — the base model narrates two actions it never takes; PhoneLLM takes both (PhoneLLM Alpha 1 model card, image 02).

The failure mode is precisely the one the card's prose names: "LLMs will often say 'Yes, I've booked that table for you' without actually doing it." It's a real gap, not a strawman — the base model's sentence is a completely reasonable thing to say if the tool call had actually fired, and a customer-facing disaster if it didn't. Whether the judge panel that scores this is well-calibrated against the human labels the card describes is not something a model card alone can settle. What the model card's own transcript does settle is that this specific failure is real and reproducible on the identical two-turn conversation, and that the fine-tune fixes it on that conversation.

Where the 1,293 milliseconds actually go

A 15-stage voice-to-voice latency budget table: macOS mic input 40ms, opus encoding 21ms, network stacks and transit 10ms, packet handling 2ms, jitter buffer 40ms, opus decoding 1ms, transcription and endpointing 300ms, LLM TTFB 650ms, sentence aggregation 20ms, TTS TTFB 120ms, opus encoding 21ms, packet handling 2ms, network stacks and transit 10ms, jitter buffer 40ms, opus decoding 1ms, macOS speaker output 15ms, total 1,293ms.
Every stage between a caller finishing a sentence and hearing the agent's answer, added by hand — the fifteen numbers sum to exactly 1,293ms as printed (PhoneLLM Alpha 1 model card, image 04).

That table is worth adding up, because it's an easy place for a stray typo to hide and it doesn't have one: 40 + 21 + 10 + 2 + 40 + 1 + 300 + 650 + 20 + 120 + 21 + 2 + 10 + 40 + 1 + 15 = 1,293, matching the card's printed total exactly. That 650ms figure is a reference architecture's LLM time-to-first-token target (from a linked, separate voice-agent latency breakdown), not a PhoneLLM-specific measurement — and it's 50.3% of the whole voice-to-voice budget, the single largest of the fifteen stages by a wide margin. Every other stage is fixed by the audio pipeline (capture, codec, network, jitter buffering, playback) or the STT/TTS models sitting next to the LLM, not by which LLM is in the loop. That makes the LLM stage the one lever this card's own numbers say is worth pulling, and PhoneLLM's own leaderboard entry says it pulls harder than the reference target assumed:

voice-to-voice budget, 643ms fixed + one LLM stage
A stacked bar of the non-LLM voice pipeline, 643 milliseconds fixed, plus PhoneLLM Alpha 1's P50 time-to-first-answer-token of 331 milliseconds, totalling 974 milliseconds against a 1,500 millisecond target. This total is inside the target.0500100015002000250030001,500ms targettotal 974msLLM 331ms

Everything except the highlighted segment is fixed by the audio pipeline — 643ms of capture, transcription, sentence aggregation, TTS-to-first-byte, and playback that no LLM choice changes. The card’s own worked example fills that slot with a reference architecture’s 650ms LLM time-to-first-token target, for a printed total of 1,293ms. At PhoneLLM’s own measured 331ms P50 instead — its real PhoneBench leaderboard figure, not the target — the same pipeline totals only 974ms, 319ms under the card’s own worked example. Currently showing that same row.

Set the picker to PhoneLLM's own P50 and the pipeline totals 974ms, not 1,293 — because PhoneLLM's actual measured PhoneBench TTFAT (331ms, from the leaderboard) is well under the 650ms target the card's worked example assumed for that slot. Holding the same fixed 643ms and swapping in Claude Sonnet 5's P95 instead pushes the pipeline to 2,809ms, 87% over the card's stated 1,500ms voice-to-voice target — not because the audio pipeline changed, but because one number in a 15-number sum swung by over two seconds. The "1,300ms faster P95 time-to-first-token" claim against GPT-5.6 Terra also holds up against the leaderboard's own numbers: Terra's P95 is 1,957ms, PhoneLLM's is given as "~600ms," and 1,957 − 600 = 1,357 — close enough to "1,300ms" that the approximation in the card's own "~600" is doing the rounding, not an inflated claim.

94% cheaper, and the arithmetic that gets there

The cost side of the story starts from a real, confirmed number: Modal's published B200 rate is $6.25/hour, and the card's $6.2496/hour figure matches it. From there the card walks through a specific worked example — region pinning, target utilization, concurrency — to arrive at a cost-per-minute figure for running PhoneLLM on a dedicated Modal endpoint.

the card’s own worked example, live1x B200 · Modal dedicated endpoint
region multiplier1.50x
utilization70%
concurrent agents (N)88
$6.2496/hr × 1.50 ÷ 0.70$13.3920/hr
÷ 60$0.2232/min
÷ 88 concurrent agents$0.00254/min
card’s printed result: $0.00025/minspreadsheet + leaderboard both list: $0.0025/min

Leave every slider at the card’s own shipped defaults — this is that exact setting — and dividing $0.2232/min by 88 comes out to $0.00254/min, not the printed $0.00025. That correct number is not a reconstruction — it’s what the model card’s own linked cost-estimator spreadsheet and its own leaderboard chart already say for this exact row, independently of this arithmetic. The error is isolated to one printed sentence; every number that generates it, and every number that cross-checks it elsewhere on the same page, is correct.

Every step up to the second-to-last is exact: $6.2496 × 1.5 (region multiplier) = $9.3744/hour; ÷ 0.70 (target utilization) = $13.392/hour, or $0.2232/minute — both numbers the card states and both correct. The last step — "Dividing $0.2232/minute by 88 concurrent agents equals a per-minute agent cost of $0.00025" — isn't: 0.2232 ÷ 88 = 0.002536, roughly ten times the printed figure. This isn't just a hand-recomputation disagreeing with prose. The card links its own cost-estimator spreadsheet, and that spreadsheet's own row for "PhoneLLM 30B Alpha 1" lists $0.0025/min — matching the correct division, not the $0.00025 sentence a few paragraphs above it. The leaderboard chart earlier in the same document lists the identical $0.0025 figure a third time. The error is contained to one sentence; everything that generates the correct number, and everything that would let a reader catch the mistake, is sitting on the same page.

The "94% cheaper than GPT-5.6 Terra" framing is close but not exact once the corrected $0.0025 figure is used: Terra's leaderboard cost is $0.0347/min, and (0.0347 − 0.0025) / 0.0347 = 92.8%, not 94% — a real but modest overstatement, about 1.2 percentage points, most plausibly from a slightly different snapshot of the same live, publicly-editable spreadsheet (its slider assumptions for conversation length and zero-data-retention pricing only affect the token-priced API rows, Terra among them, and are explicitly adjustable by anyone with the link).

What ships, and what the defaults actually do

The card is explicit about how to run this model: "set temperature to 0 and disable thinking. These two settings align with how the model was trained." Neither is what a naive load defaults to. generation_config.json ships "do_sample": true with no temperature key at all — which means an unmodified model.generate() call samples at the library default of 1.0, not the recommended greedy temperature=0. The chat template's own Jinja carries {%- set enable_thinking = enable_thinking if enable_thinking is defined else True %} — thinking is on by default unless a caller explicitly passes chat_template_kwargs: {"enable_thinking": false}, which is exactly the override the README tells you to pass and exactly the setting that isn't the file's own default. The repo does ship the plumbing for the recommended path correctly — a custom nano_v3_reasoning_parser.py for vLLM specifically handles the case where thinking is disabled and the model's answer would otherwise land in the wrong field — so the "right" configuration is fully supported. It just isn't what you get by not reading the README.

The license is a genuine two-layer arrangement, not just a BSD stamp: PhoneLLM's own terms are BSD 2-Clause, but it's a derivative of NVIDIA's Nemotron 3 Nano checkpoint, which ships under the NVIDIA Nemotron Open Model License. That upstream license's Section 3 (Redistribution) survives the fine-tune and binds anyone who redistributes PhoneLLM or a derivative of it: include a copy of the NVIDIA license, retain NVIDIA's copyright/attribution notices, and — if the work carries a NOTICE file — propagate an attribution statement crediting NVIDIA. BSD 2-Clause governs Pipecat's own modifications and the model as a whole, as the NVIDIA license's Section 3 permits, but it doesn't erase the upstream obligations; both licenses apply, layered rather than replaced.

The ledger

What holds up: the 3.580B-active / 31.578B-total math, to three significant figures, verified from the raw tensor shapes rather than taken from the README. The 1,293ms latency-budget sum, added by hand, exact. The base-model comparison, which is really the strongest evidence in the whole card — a fine-tune that changes score by 43.7 points while provably changing nothing about cost or latency, because the two models are computing on the same graph. The "1,300ms faster P95" claim, which survives being checked against the leaderboard's own numbers. What doesn't: one arithmetic step in the cost walkthrough, off by roughly 10x and contradicted twice on the same page — a real error, but a narrow and easily-fixed one, not a sign the underlying cost numbers are made up. And a "94% cheaper" headline that rounds up from a real, still-compelling 92.8%.

None of this changes the shape of the actual result: a 30B-parameter, 3.5B-active MoE, full-parameter fine-tuned for phone-agent tool use, scoring within a point of a much larger frontier model on a benchmark built specifically to catch the failure mode voice agents actually have — while costing about a fourteenth as much per minute, at a P50 latency low enough that the LLM stops being the tightest part of the voice-to-voice budget. That claim was checkable, and it checks out. The one line that didn't just happened to be the one nobody re-derived before publishing.


More on the pieces underneath: the Mamba-Transformer-MoE hybrid architecture PhoneLLM inherits shows up again in TwoTower, also a 30B Nemotron hybrid; the sparse-routing mechanics generally are in Mixture of Experts, from scratch; the say/do consistency problem gets a very different fix in VoiceMem's retrieval-side memory architecture; and the serving stacks the card recommends are covered in vLLM and SGLang. The overlapping-stage streaming design in the voice loop itself is close kin to the turn-detection tricks in speech-to-speech.

Cite this article

For attribution, please use the following reference or BibTeX:

Satyajit Ghana, "PhoneLLM Alpha 1: the fine-tune is free, the cost line isn't", ai.thesatyajit.com, August 2026.

bibtex
@misc{ghana2026phonellmalpha1,
  author = {Satyajit Ghana},
  title  = {PhoneLLM Alpha 1: the fine-tune is free, the cost line isn't},
  url    = {https://ai.thesatyajit.com/articles/phonellm-alpha-1},
  year   = {2026}
}
share