Text Generation
Transformers
PyTorch
constrained-decoding
reachability
logit-processor
structured-generation
grammar-masking
dfa
fsm
Instructions to use uuugi/gclm-constrained-decoding with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use uuugi/gclm-constrained-decoding with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="uuugi/gclm-constrained-decoding")# Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("uuugi/gclm-constrained-decoding", device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use uuugi/gclm-constrained-decoding with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "uuugi/gclm-constrained-decoding" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "uuugi/gclm-constrained-decoding", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/uuugi/gclm-constrained-decoding
- SGLang
How to use uuugi/gclm-constrained-decoding 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 "uuugi/gclm-constrained-decoding" \ --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": "uuugi/gclm-constrained-decoding", "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 "uuugi/gclm-constrained-decoding" \ --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": "uuugi/gclm-constrained-decoding", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }' - Docker Model Runner
How to use uuugi/gclm-constrained-decoding with Docker Model Runner:
docker model run hf.co/uuugi/gclm-constrained-decoding
Fix markdown table pipe escaping and KaTeX cases rendering
Browse files
README.md
CHANGED
|
@@ -40,11 +40,11 @@ GCLM mathematically guarantees that an LLM will strictly reach designated goal/a
|
|
| 40 |
|
| 41 |
| Feature | Standard Forward DFA (Outlines / SGLang) | **GCLM (Ours)** |
|
| 42 |
| :--- | :--- | :--- |
|
| 43 |
-
| **Masking Basis** | Current state validity ($s_{\text{curr}} \to s'$) | **Time-bounded backward reachability** ($s_{\text{curr}} \to s' \
|
| 44 |
| **Dead-End Traps** | ❌ May enter valid forward branches that lead to dead-ends | ✅ **Preemptively masked** before entering trap |
|
| 45 |
| **Token Budget Exceeded**| ❌ Outputs truncated/broken syntax when budget ends | ✅ **Forces early syntax closure** before budget exhaustion |
|
| 46 |
| **Per-Token Overhead** | $O(1)$ table lookup | **Strict $O(1)$ vectorized PyTorch lookup (< 0.1ms)** |
|
| 47 |
-
| **Complexity Scaling** | Scales with active state transitions | **Zero runtime dependence on state count
|
| 48 |
|
| 49 |
---
|
| 50 |
|
|
@@ -54,32 +54,24 @@ GCLM mathematically guarantees that an LLM will strictly reach designated goal/a
|
|
| 54 |
Given an FSM $(S, \Sigma, \delta, s_0, S_{\mathrm{goal}})$ and maximum token budget $T_{\max}$, we precompute a reachability tensor $R \in \mathbb{B}^{(T_{\max} + 1) \times |S|}$ via vectorized backward BFS:
|
| 55 |
|
| 56 |
$$
|
| 57 |
-
R[0, s] =
|
| 58 |
-
\begin{cases}
|
| 59 |
-
\mathrm{True} & \text{if } s \in S_{\mathrm{goal}} \\
|
| 60 |
-
\mathrm{False} & \text{otherwise}
|
| 61 |
-
\end{cases}
|
| 62 |
$$
|
| 63 |
|
| 64 |
For $t = 1, \dots, T_{\max}$:
|
| 65 |
|
| 66 |
$$
|
| 67 |
-
R[t, s] = R[t-1, s] \;\lor\; \left( \exists v \in \mathcal{V} \text{ s.t. } \delta(s, v) \ge 0 \;\land\; R[t-1, \delta(s, v)] = \
|
| 68 |
$$
|
| 69 |
|
| 70 |
### 2. Strict $O(1)$ Runtime Logits Masking
|
| 71 |
At decoding step $k$ with remaining budget $T_{\text{rem}} = T_{\max} - k$:
|
| 72 |
|
| 73 |
$$
|
| 74 |
-
\
|
| 75 |
$$
|
| 76 |
|
| 77 |
$$
|
| 78 |
-
\
|
| 79 |
-
\begin{cases}
|
| 80 |
-
\mathrm{Logits}[v] & \text{if } \mathrm{ValidTokens}(v) = \mathrm{True} \\
|
| 81 |
-
-\infty & \text{otherwise}
|
| 82 |
-
\end{cases}
|
| 83 |
$$
|
| 84 |
|
| 85 |
---
|
|
@@ -151,15 +143,14 @@ gclm_project/
|
|
| 151 |
### 4. FSM Complexity & Strict $O(1)$ Runtime Scaling
|
| 152 |
> Scaling state count $|S|$ from 10 to 10,000 (1,000x increase). Plot saved as `paper_figure_scaling.png`.
|
| 153 |
|
| 154 |
-
| Vocabulary Size
|
| 155 |
| :--- | :---: | :---: | :---: | :---: |
|
| 156 |
-
| **
|
| 157 |
-
|
|
| 158 |
-
|
|
| 159 |
-
|
|
| 160 |
-
| **
|
| 161 |
-
|
|
| 162 |
-
| $\vert\mathcal{V}\vert = 151,643$ | **$\vert S\vert = 10,000$** | 147,702.79 ms | 11.56 GB | **666.22 $\mu$s** ($\mathcal{O}(1)$ empirically verified) |
|
| 163 |
|
| 164 |
---
|
| 165 |
|
|
|
|
| 40 |
|
| 41 |
| Feature | Standard Forward DFA (Outlines / SGLang) | **GCLM (Ours)** |
|
| 42 |
| :--- | :--- | :--- |
|
| 43 |
+
| **Masking Basis** | Current state validity ($s_{\text{curr}} \to s'$) | **Time-bounded backward reachability** ($s_{\text{curr}} \to s' \to^* S_{\text{goal}}$ in $\le T_{\text{rem}}-1$ steps) |
|
| 44 |
| **Dead-End Traps** | ❌ May enter valid forward branches that lead to dead-ends | ✅ **Preemptively masked** before entering trap |
|
| 45 |
| **Token Budget Exceeded**| ❌ Outputs truncated/broken syntax when budget ends | ✅ **Forces early syntax closure** before budget exhaustion |
|
| 46 |
| **Per-Token Overhead** | $O(1)$ table lookup | **Strict $O(1)$ vectorized PyTorch lookup (< 0.1ms)** |
|
| 47 |
+
| **Complexity Scaling** | Scales with active state transitions | **Zero runtime dependence on state count (\|S\|)** |
|
| 48 |
|
| 49 |
---
|
| 50 |
|
|
|
|
| 54 |
Given an FSM $(S, \Sigma, \delta, s_0, S_{\mathrm{goal}})$ and maximum token budget $T_{\max}$, we precompute a reachability tensor $R \in \mathbb{B}^{(T_{\max} + 1) \times |S|}$ via vectorized backward BFS:
|
| 55 |
|
| 56 |
$$
|
| 57 |
+
R[0, s] = \begin{cases} \text{True} & \text{if } s \in S_{\text{goal}} \\ \text{False} & \text{otherwise} \end{cases}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
$$
|
| 59 |
|
| 60 |
For $t = 1, \dots, T_{\max}$:
|
| 61 |
|
| 62 |
$$
|
| 63 |
+
R[t, s] = R[t-1, s] \;\lor\; \left( \exists v \in \mathcal{V} \text{ s.t. } \delta(s, v) \ge 0 \;\land\; R[t-1, \delta(s, v)] = \text{True} \right)
|
| 64 |
$$
|
| 65 |
|
| 66 |
### 2. Strict $O(1)$ Runtime Logits Masking
|
| 67 |
At decoding step $k$ with remaining budget $T_{\text{rem}} = T_{\max} - k$:
|
| 68 |
|
| 69 |
$$
|
| 70 |
+
\text{ValidTokens}(v) = (\delta(s_{\text{curr}}, v) \ge 0) \;\land\; R\big[\min(T_{\text{rem}}-1, T_{\max}), \;\text{clamp}(\delta(s_{\text{curr}}, v), 0)\big]
|
| 71 |
$$
|
| 72 |
|
| 73 |
$$
|
| 74 |
+
\text{Logits}[v] = \begin{cases} \text{Logits}[v] & \text{if } \text{ValidTokens}(v) = \text{True} \\ -\infty & \text{otherwise} \end{cases}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 75 |
$$
|
| 76 |
|
| 77 |
---
|
|
|
|
| 143 |
### 4. FSM Complexity & Strict $O(1)$ Runtime Scaling
|
| 144 |
> Scaling state count $|S|$ from 10 to 10,000 (1,000x increase). Plot saved as `paper_figure_scaling.png`.
|
| 145 |
|
| 146 |
+
| Vocabulary Size (\|V\|) | State Count (\|S\|) | Offline BFS Time | Memory Footprint | Online Latency per Token |
|
| 147 |
| :--- | :---: | :---: | :---: | :---: |
|
| 148 |
+
| **\|V\| = 32,000 (LLaMA)** | \|S\| = 10 | 29.55 ms | 2.44 MB | **388.72 µs** |
|
| 149 |
+
| \|V\| = 32,000 | \|S\| = 100 | 240.10 ms | 24.42 MB | **335.10 µs** |
|
| 150 |
+
| \|V\| = 32,000 | \|S\| = 1,000 | 2,111.82 ms | 244.19 MB | **340.84 µs** |
|
| 151 |
+
| \|V\| = 32,000 | **\|S\| = 10,000** | 25,790.14 ms | 2.44 GB | **356.29 µs** ($O(1)$ empirically verified) |
|
| 152 |
+
| **\|V\| = 151,643 (Qwen2.5)** | \|S\| = 10 | 159.29 ms | 11.57 MB | **601.92 µs** |
|
| 153 |
+
| \|V\| = 151,643 | **\|S\| = 10,000** | 147,702.79 ms | 11.56 GB | **666.22 µs** ($O(1)$ empirically verified) |
|
|
|
|
| 154 |
|
| 155 |
---
|
| 156 |
|