> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sglang.io/llms.txt
> Use this file to discover all available pages before exploring further.

# PPLX-Decider-v1.1-27B

> Deploy PPLX-Decider-v1.1-27B with SGLang. Perplexity's updated decision model reads the whole prompt in its full-attention layers and returns calibrated probabilities for choice, yes or no, and score questions on /v1/systemone, on one NVIDIA GB300 or H200 in BF16.

## Deployment

> **Install SGLang**
>
> For all methods and hardware platforms, see the [official SGLang installation guide](https://docs.sglang.io/docs/get-started/install.md). The two paths below match the **Python / Docker** toggle in the command panel. PPLX-Decider-v1.1 support lands in [#42645](https://github.com/sgl-project/sglang/pull/42645), after v0.5.21, so until a release includes it, install a [nightly build](https://docs.sglang.io/docs/get-started/install.md#nightly-builds) built after that merge.
>
> **Python (pip / uv)**
>
> ```bash Command theme={null}
> pip install --upgrade pip
> pip install uv
> uv pip install --prerelease=allow --index-strategy unsafe-best-match --extra-index-url https://docs.sglang.ai/whl/cu130/ sglang
> ```
>
> Then run the **Python** output of the command panel below in that environment.
>
> **Docker**
>
> ```bash Command theme={null}
> docker pull lmsysorg/sglang:dev
> ```
>
> The image is multi-arch, so the same tag runs on x86 H200 hosts and Arm GB300 hosts. For how to launch it, see [Install → Method 3: Using Docker](https://docs.sglang.io/docs/get-started/install.md#method-3-using-docker). Substitute the inner `sglang serve ...` with what the command generator below produces.

Pick your GPU to generate the launch command. The model runs on one GPU in BF16 and needs no flag: SGLang reads the checkpoint's `decision_config.json`, runs the full-attention layers over the whole prompt as the model was trained, and turns off the radix cache and chunked prefill, which would show those layers only part of the prompt.

> [!NOTE]
>
> The GB300 recipe was measured end to end on one GB300 at [#42645](https://github.com/sgl-project/sglang/pull/42645): four request shapes from 1 to 256 concurrent requests, Belebele and WinoGrande accuracy, and per-question parity with the checkpoint's own reference implementation. The H200 command is the same and has not been run yet. [§3](#3-benchmarks) has the method and the full tables.

## Playground

The Playground layers SGLang features on top of the recipe above. Any override changes the badge to **Not Verified** until that exact configuration is tested end to end. The [Configuration Tips](#2-configuration-tips) say which overrides were measured on GB300. Tensor parallelism times data-parallel replicas must fit the GPUs on one node.

## 1. Model Introduction

**PPLX-Decider-v1.1-27B** is the successor to [PPLX-Decider-v1-27B](https://docs.sglang.io/cookbook/autoregressive/Perplexity/PPLX-Decider-v1-27B.md), Perplexity's decision model fine-tuned from [Qwen3.8-27B](https://docs.sglang.io/cookbook/autoregressive/Qwen/Qwen3.8-27B.md) under the Apache-2.0 license. Like v1, it replaces the language model head with a readout over 255 answer codes and answers choice, yes or no (`noul`), and score questions about a text state and optional images with a probability for every option, without generating text.

Two things changed. The 16 full-attention layers no longer use a causal mask, so every token attends to the whole prompt, while the 48 Gated DeltaNet layers stay causal. And training grew from 73,000 to 626,033 rows, most of them from [tasksource](https://github.com/sileod/tasksource). The prompt format, answer codes, and readout layout are the same as v1's, but the calibrated temperature is 1.0087 instead of 2.2076, so probabilities from the two versions are not interchangeable.

<table>
  <colgroup>
    <col />

    <col />
  </colgroup>

  <thead>
    <tr>
      <th>Property</th>
      <th>Value</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>Checkpoint</td>
      <td>[perplexity-ai/pplx-decider-v1.1-27b](https://huggingface.co/perplexity-ai/pplx-decider-v1.1-27b) (BF16)</td>
    </tr>

    <tr>
      <td>Base model</td>
      <td>Qwen3.8-27B, one epoch of supervised fine-tuning on 626,033 decision rows (530,103 from tasksource)</td>
    </tr>

    <tr>
      <td>Attention</td>
      <td>Noncausal in the 16 full-attention layers, causal in the 48 Gated DeltaNet layers</td>
    </tr>

    <tr>
      <td>Question types</td>
      <td>`choice` (up to 255 options), `noul` (yes or no), `score` (up to 10 levels)</td>
    </tr>

    <tr>
      <td>Inputs</td>
      <td>Text or JSON state, optional images</td>
    </tr>

    <tr>
      <td>Prompt length</td>
      <td>Trained on question prompts of up to 8,192 tokens, and the backbone accepts 262,144</td>
    </tr>

    <tr>
      <td>License</td>
      <td>Apache-2.0</td>
    </tr>
  </tbody>
</table>

Perplexity reports a Decision Index of 61.56 for v1.1, up from 56.4 for v1:

<table>
  <colgroup>
    <col />

    <col />

    <col />

    <col />
  </colgroup>

  <thead>
    <tr>
      <th>Decision Index category</th>
      <th>Jev</th>
      <th>PPLX-Decider-v1-27B</th>
      <th>PPLX-Decider-v1.1-27B</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>Knowledge</td>
      <td>**51.4**</td>
      <td>40.9</td>
      <td>48.18</td>
    </tr>

    <tr>
      <td>Language</td>
      <td>62.0</td>
      <td>63.5</td>
      <td>**69.45**</td>
    </tr>

    <tr>
      <td>Retrieval</td>
      <td>55.4</td>
      <td>54.9</td>
      <td>**61.26**</td>
    </tr>

    <tr>
      <td>Tools</td>
      <td>75.1</td>
      <td>**79.3**</td>
      <td>78.88</td>
    </tr>

    <tr>
      <td>Arts</td>
      <td>37.7</td>
      <td>39.4</td>
      <td>**44.66**</td>
    </tr>

    <tr>
      <td>**Overall**</td>
      <td>57.9</td>
      <td>56.4</td>
      <td>**61.56**</td>
    </tr>
  </tbody>
</table>

**Resources:** [HuggingFace](https://huggingface.co/perplexity-ai/pplx-decider-v1.1-27b), [reference model code](https://huggingface.co/perplexity-ai/pplx-decider-v1.1-27b/blob/main/source/src/autojev/model.py), [Decision models in SGLang](https://docs.sglang.io/docs/supported-models/decision_models.md).

## 2. Configuration Tips

* **Route.** Send requests to `/v1/systemone`, the System One API the checkpoint was trained for. `/v1/decisions` refuses this checkpoint because its labels and prompt are not the ones the readout learned, and chat or generation requests are not meaningful without a language model head.
* **Clients.** Clients of the System One API, including the TypeSafe SDKs, work by pointing their base URL at the server. See [System One compatible API](https://docs.sglang.io/docs/supported-models/decision_models.md#system-one-compatible-api) for the request and response reference.
* **Images.** Pass each image in `images` as base64 bytes, a base64 data URL, or an `http(s)` URL. They precede the text in every question. The processor resizes every image to between 65,536 and 262,144 pixels, so one image costs 64 to 256 prompt tokens.
* **Noncausal attention is automatic.** SGLang reads `attention_mode: noncausal_full_attention` from `decision_config.json` and runs the full-attention layers as encoder layers, which the TRT-LLM, FlashInfer, and Triton attention backends support. It also turns off the radix cache and chunked prefill, logging `Radix cache and chunked prefill are disabled for a decision checkpoint with noncausal full attention`: a cached prefix or a prefill chunk would see only part of a prompt whose every position depends on the rest. These two settings override any flag you pass. A prompt longer than the 16,384-token prefill budget is still read in one pass: an 18,585-token prompt matched the reference implementation to four decimal places on GB300.
* **No prefix reuse.** Because every layer output depends on the whole prompt, nothing carries over between requests, not even an identical one. The cost of a request is roughly *questions × prompt tokens*, as on v1.
* **Prompt length.** Like v1, the model was trained on question prompts of up to 8,192 tokens, and the reference code refuses longer ones. SGLang serves longer prompts in one pass, but their accuracy is untested.
* **Attention backend.** On GB300, Auto resolves to the TRT-LLM kernel with 64-token pages. `--attention-backend flashinfer` and `--attention-backend triton` matched the reference implementation as closely, with the same top option on 99.8% of the accuracy items. The H200 path has not been run yet.
* **Speed.** One GB300 reads about 27,000 prompt tokens per second once batches are full, the same as v1. Measured back to back on the same GPU against v1's recipe, v1.1 was within 2% on short questions and four-question requests, and an 8K-token state saturated 6% lower (3.13 against 3.32 requests per second), because noncausal attention computes the full attention matrix in its 16 full-attention layers instead of half of it.
* **More GPUs.** The backbone and prompt sizes are v1's, so the [v1 page's scaling measurements](https://docs.sglang.io/cookbook/autoregressive/Perplexity/PPLX-Decider-v1-27B.md#2-configuration-tips) are the reference: data-parallel replicas (`--dp-size N`) for throughput, tensor parallelism only for latency on long prompts. They were not repeated for v1.1.
* **Upgrading from v1.** Re-check any thresholds you tuned on v1 probabilities: v1.1 has a different temperature and changed its top answer on 8% of the Belebele and WinoGrande items.

## 3. Benchmarks

All numbers in this section come from one NVIDIA GB300 (288 GB) at [#42645](https://github.com/sgl-project/sglang/pull/42645), with checkpoint revision `3b45dea`, served with the GB300 recipe above unless a row says otherwise. The method and request shapes are those of the [v1 page](https://docs.sglang.io/cookbook/autoregressive/Perplexity/PPLX-Decider-v1-27B.md#3-benchmarks), whose speed script works here unchanged.

### 3.1 Speed

<table>
  <colgroup>
    <col />

    <col />

    <col />

    <col />

    <col />
  </colgroup>

  <thead>
    <tr>
      <th>Request</th>
      <th>Concurrent</th>
      <th>Median latency</th>
      <th>Requests/s</th>
      <th>Prompt tokens/s</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>Short question, 382 tokens</td>
      <td>1</td>
      <td>53 ms</td>
      <td>18.9</td>
      <td>7,203</td>
    </tr>

    <tr>
      <td />

      <td>4</td>
      <td>106 ms</td>
      <td>37.6</td>
      <td>14,362</td>
    </tr>

    <tr>
      <td />

      <td>16</td>
      <td>275 ms</td>
      <td>57.4</td>
      <td>21,909</td>
    </tr>

    <tr>
      <td />

      <td>64</td>
      <td>931 ms</td>
      <td>67.5</td>
      <td>25,770</td>
    </tr>

    <tr>
      <td />

      <td>256</td>
      <td>3,489 ms</td>
      <td>71.1</td>
      <td>27,139</td>
    </tr>

    <tr>
      <td>Four questions on a 1K-token state, 4,540 tokens</td>
      <td>1</td>
      <td>183 ms</td>
      <td>5.5 (22 decisions/s)</td>
      <td>24,782</td>
    </tr>

    <tr>
      <td />

      <td>8</td>
      <td>1,315 ms</td>
      <td>6.0 (24 decisions/s)</td>
      <td>27,398</td>
    </tr>

    <tr>
      <td />

      <td>32</td>
      <td>4,882 ms</td>
      <td>6.1 (24 decisions/s)</td>
      <td>27,649</td>
    </tr>

    <tr>
      <td>8K-token state, 8,224 tokens</td>
      <td>1</td>
      <td>334 ms</td>
      <td>2.99</td>
      <td>24,620</td>
    </tr>

    <tr>
      <td />

      <td>4</td>
      <td>1,280 ms</td>
      <td>3.12</td>
      <td>25,682</td>
    </tr>

    <tr>
      <td />

      <td>16</td>
      <td>5,101 ms</td>
      <td>3.13</td>
      <td>25,726</td>
    </tr>

    <tr>
      <td>One 1024×768 image, 429 tokens</td>
      <td>1</td>
      <td>118 ms</td>
      <td>8.3</td>
      <td>3,541</td>
    </tr>

    <tr>
      <td />

      <td>16</td>
      <td>466 ms</td>
      <td>33.6</td>
      <td>14,398</td>
    </tr>

    <tr>
      <td />

      <td>64</td>
      <td>1,197 ms</td>
      <td>49.9</td>
      <td>21,416</td>
    </tr>
  </tbody>
</table>

### 3.2 Accuracy and parity

Both sets go through `/v1/systemone` as one `choice` question per item, with the same conversion as the v1 page. The reference rows run the same items through the checkpoint's own `DecisionModel` one at a time.

<table>
  <colgroup>
    <col />

    <col />

    <col />
  </colgroup>

  <thead>
    <tr>
      <th>Implementation</th>
      <th>Belebele (eng\_Latn, 900)</th>
      <th>WinoGrande (xl dev, 1,267)</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>SGLang, GB300 recipe (TRT-LLM attention)</td>
      <td>**97.67%**</td>
      <td>**92.42%**</td>
    </tr>

    <tr>
      <td>SGLang, `--attention-backend flashinfer`</td>
      <td>97.67%</td>
      <td>92.58%</td>
    </tr>

    <tr>
      <td>SGLang, `--attention-backend triton`</td>
      <td>97.67%</td>
      <td>92.42%</td>
    </tr>

    <tr>
      <td>Checkpoint's reference `DecisionModel` (Transformers, BF16, GB300)</td>
      <td>97.67%</td>
      <td>92.50%</td>
    </tr>

    <tr>
      <td>v1.1 served with causal attention, as SGLang did before #42645</td>
      <td>97.00%</td>
      <td>88.87%</td>
    </tr>

    <tr>
      <td>PPLX-Decider-v1-27B on SGLang, for comparison</td>
      <td>96.67%</td>
      <td>84.21%</td>
    </tr>
  </tbody>
</table>

Against the reference implementation, the recipe picks the same option on 2,164 of 2,167 items, and each of the three differences is a near-tie within 0.031 of an even split. Per item, the largest probability difference averages 0.002 (99th percentile 0.030, maximum 0.089). Prompts of 11,099 and 18,585 tokens, an image question, and a score question also matched the reference, the largest difference being 0.015 on the score question. Served with causal attention instead, v1.1 changed its top answer on 101 of the 2,167 items and lost 3.6 points on WinoGrande.

> **Check accuracy on your deployment (Python)**
>
> ```python Example theme={null}
> import asyncio
>
> import aiohttp
> from datasets import load_dataset
>
> URL = "http://localhost:30000/v1/systemone"
>
>
> async def main():
>     rows = load_dataset("facebook/belebele", "eng_Latn", split="test")
>     limit = asyncio.Semaphore(32)
>
>     async def ask(session, row):
>         body = {
>             "model": "perplexity-ai/pplx-decider-v1.1-27b",
>             "state": row["flores_passage"],
>             "questions": {
>                 "answer": {
>                     "type": "choice",
>                     "instructions": row["question"],
>                     "criteria": {str(k): row[f"mc_answer{k}"] for k in range(1, 5)},
>                 }
>             },
>         }
>         async with limit, session.post(URL, json=body) as response:
>             response.raise_for_status()
>             answer = (await response.json())["answers"]["answer"]
>         return answer["choice"] == row["correct_answer_num"]
>
>     async with aiohttp.ClientSession() as session:
>         correct = await asyncio.gather(*(ask(session, row) for row in rows))
>     print(f"Belebele eng_Latn: {sum(correct)}/{len(correct)} = {100 * sum(correct) / len(correct):.2f}%")
>
>
> asyncio.run(main())
> ```

> **Example Output**
>
> ```text Output theme={null}
> Belebele eng_Latn: 879/900 = 97.67%
> ```

## 4. Advanced Usage

### 4.1 Text Decisions

> **Text Decision Example (Python)**
>
> ```python Example theme={null}
> import requests
>
> response = requests.post(
>     "http://localhost:30000/v1/systemone",
>     json={
>         "model": "perplexity-ai/pplx-decider-v1.1-27b",
>         "state": "My Stripe integration keeps failing. I'm losing sales. Please help ASAP.",
>         "questions": {
>             "routing": {
>                 "type": "choice",
>                 "instructions": "Which team should handle this request?",
>                 "criteria": {
>                     "billing": "Charges and refunds",
>                     "technical_support": "Integration errors",
>                     "sales": "Questions about buying a product",
>                 },
>             },
>             "urgency": {"type": "noul", "instructions": "Does this message express urgency?"},
>         },
>     },
>     timeout=60,
> )
> response.raise_for_status()
> for name, answer in response.json()["answers"].items():
>     print(name, answer)
> ```

> **Example Output**
>
> ```text Output theme={null}
> routing {'type': 'choice', 'choice': 'technical_support', 'confidence': 0.9977658531751561, 'probabilities': {'billing': 0.0014030901008239556, 'technical_support': 0.9985105687834377, 'sales': 8.634111573847184e-05}}
> urgency {'type': 'noul', 'noul': 0.9995671977710632}
> ```

### 4.2 Image Decisions

The example output below came from a 512×512 solid red test image.

> **Image Decision Example (Python)**
>
> ```python Example theme={null}
> import base64
> from pathlib import Path
>
> import requests
>
> image = base64.b64encode(Path("screenshot.png").read_bytes()).decode("ascii")
> response = requests.post(
>     "http://localhost:30000/v1/systemone",
>     json={
>         "model": "perplexity-ai/pplx-decider-v1.1-27b",
>         "state": "Look at the supplied image.",
>         "images": [image],
>         "questions": {
>             "color": {
>                 "type": "choice",
>                 "instructions": "What is the dominant color?",
>                 "criteria": {"red": "Red", "green": "Green", "blue": "Blue", "other": "Another color"},
>             }
>         },
>     },
>     timeout=60,
> )
> response.raise_for_status()
> print(response.json()["answers"]["color"])
> ```

> **Example Output**
>
> ```text Output theme={null}
> {'type': 'choice', 'choice': 'red', 'confidence': 0.9989117512916561, 'probabilities': {'red': 0.9991838134687421, 'green': 6.743375714875418e-05, 'blue': 8.12085765657198e-05, 'other': 0.0006675441975434462}}
> ```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.