CLM-8B Explained: How Contrastive Language Models Turn LLMs Into Fast Decision and Verification Engines

CLM-8B Explained: How Contrastive Language Models Turn LLMs Into Fast Decision and Verification Engines
A language model normally answers questions by generating language.
A new model family called Contrastive Language Models, or CLMs, takes a different route.
Instead of asking the model to generate:
"The best action is to restart the database."
CLM can compare:
current state
↓
candidate action 1
candidate action 2
candidate action 3
candidate action 4
and determine which candidate best matches the state.
That seemingly small change leads to a very different architecture.
The first publicly released model is CLM-v0.1-8B.
Its core consists of a frozen Qwen3-8B encoder with two small trainable projection heads:
State head
Action head
The model is trained with a bidirectional InfoNCE contrastive objective.
What is CLM?
CLM stands for Contrastive Language Model.
The project positions CLM as another type of System One model designed for fast structured decisions.
But its design philosophy is different from simply creating another classification head.
The key abstraction is:
The model learns to put compatible states and actions close together in a shared representation space.
For example:
State:
"The database connection has failed."
Candidate actions:
A1 = restart database
A2 = open Photoshop
A3 = send marketing email
A4 = inspect database logs
The model wants something approximately like:
similarity(state, A1) → high
similarity(state, A4) → high
similarity(state, A2) → low
similarity(state, A3) → low
Once that representation exists, decision-making becomes a ranking problem.
The architecture
The architecture is unusually simple compared with a conventional generative LLM.
At the center is Qwen3-8B.
The official model card describes CLM-8B as:

The Qwen3-8B backbone provides the semantic representation.
The two projection heads transform that representation into spaces suitable for state/action compatibility scoring.
The public repository describes each projection head as approximately 20 million trainable parameters, while the Qwen3-8B encoder remains frozen.
That means the training and serving problem is substantially different from fine-tuning all 8 billion parameters.
Why freeze Qwen3?
Qwen3-8B already contains a large amount of semantic knowledge.
CLM doesn't need to relearn that knowledge from scratch.
Instead, the contrastive heads learn a new representation:
"What does this state mean?"
and
"What does this action mean?"
then learn how those representations should align.
So the model effectively repurposes a generative LLM as a semantic encoder.
Qwen3-8B itself is an 8.2-billion-parameter causal language model with 36 layers and GQA attention, while the CLM system uses it in pooling/embedding mode rather than performing ordinary next-token generation.
The core idea: state/action disaggregation
This is arguably the most interesting engineering idea in CLM.
Imagine a tool ecosystem with 10,000 possible actions.
Many of those actions don't change very often.
For example:
restart_database()
search_web()
open_file()
run_tests()
deploy_service()
Their representations can be computed once.
restart_database()
↓
action embedding
search_web()
↓
action embedding
run_tests()
↓
action embedding
Those embeddings can then be reused across many different states.
The model doesn't need to repeatedly interpret every candidate action from scratch.
The CLM repository explicitly describes this as state and action caching.
This leads to an architecture like:

This is especially attractive when the number of possible actions is large.
Contrastive learning
This is where the "CLM" part comes from.
Suppose we have a batch of matched state/action pairs:
State 1 ↔ Action 1
State 2 ↔ Action 2
State 3 ↔ Action 3
State 4 ↔ Action 4
The model should learn:
State 1 ↔ Action 1 high similarity
State 1 ↔ Action 2 low similarity
State 1 ↔ Action 3 low similarity
State 1 ↔ Action 4 low similarity
The same principle should work in the opposite direction:
Action 1 ↔ State 1 high similarity
Action 1 ↔ State 2 low similarity
...
CLM uses a bidirectional InfoNCE loss for exactly this purpose.
A simplified form is:
where:
- () is the embedding of state ()
- () is the embedding of the correct action
- () is a temperature parameter
- () is the batch size
The training objective pulls matched pairs together and pushes mismatched pairs apart.
Why hard negatives matter
Easy negatives are not particularly useful.
Suppose:
State:
"The database is down."
Positive:
restart_database()
Negative:
bake_a_cake()
That's trivial.
The model learns much more when the negative is:
restart_database()
versus:
inspect_database_logs()
Both are plausible.
CLM's training pipeline includes approximately 30 million synthetic hard negatives during its mid-training stage.
The idea is to force the representation space to become sensitive to subtle differences between plausible actions.
CLM's training recipe
According to the current public model card, CLM-8B was trained through three major stages:
~60M Nemotron Q&A pairs
↓
pre-training
~30M synthetic hard negatives
↓
mid-training
~1M agentic trajectories
↓
post-training
This progression is important.
The first stage establishes broad semantic representation.
The second teaches discrimination between plausible and incorrect candidates.
The third exposes the model to actual agentic behavior and state/action relationships.
Turning CLM into a decision model
Suppose the state is:
"My invoice was charged twice and nobody answers the phone."
We can provide:
billing
technical
sales
The model encodes the state and the candidate descriptions.
Then it calculates compatibility scores.
Conceptually:

The official examples produce a result such as:
billing 0.93878
technical 0.06122
for the example support ticket.
CLM is not a text generator
This is worth emphasizing.
Despite the word Language Model, CLM-v0.1-8B is a ranker/decision model, not a normal generative LLM.
The model card explicitly lists this as a limitation:
CLM has no generation capability and only scores candidates that you provide.
In other words:
LLM:
prompt → generated tokens
CLM:
state + candidates → scores
This distinction is fundamental.
Free-form ranking
The system becomes much more interesting when candidates are not simple labels.
Suppose an agent has generated four possible solutions:
Solution A
Solution B
Solution C
Solution D
CLM can rank them.
The official repository exposes an Engine.rank() interface for exactly this style of use.
For example:
"""Rank candidate actions or answers against a state using CLM."""
from clm import Engine
def main() -> None:
engine = Engine(
emb_url="http://127.0.0.1:8090/v1/embeddings"
)
results = engine.rank(
"What causes tides on Earth?",
[
"The Moon's gravitational pull.",
"Photosynthesis in plants.",
"Because the Earth is round.",
],
)
for result in results:
print(result)
if __name__ == "__main__":
main()
The result is a ranking with probabilities relative to the supplied candidate set.
This makes CLM useful for:
best-of-N generation
tool selection
candidate ranking
agent action selection
retrieval reranking
solution verification
How CLM can verify an agent
This is one of the most interesting use cases.
Suppose a coding agent generates four possible solutions:
Agent
│
├── Solution A
├── Solution B
├── Solution C
└── Solution D
│
▼
CLM
│
▼
ranking
│
▼
best candidate
Rather than asking the agent itself:
"Which one of your solutions is best?"
a separate model can judge them.
That makes CLM useful as a verifier.
The current project reports that fine-tuned CLM heads were used as verifiers for DeepSWE and Terminal-Bench 2.1. The repository reports 81.6% on 38 held-out DeepSWE tasks and 87.6% on 30 held-out Terminal-Bench 2.1 tasks, with latency on H100 hardware. These are project-reported benchmark results rather than independent evaluations.
Why caching changes the economics
Suppose there are:
1,000 candidate actions
and the same action set is repeatedly evaluated against different states.
A conventional approach repeatedly processes:
state + action 1
state + action 2
...
state + action 1000
CLM can separate these:
ACTION SIDE
action 1 → embedding
action 2 → embedding
...
action 1000 → embedding
cache all of them
Then each new state only requires:
new state
↓
state embedding
↓
compare against cached action vectors
The expensive semantic encoding work for candidate actions can therefore be amortized.
The CLM authors report that this architecture is particularly advantageous when candidate sets are large or candidates are reused. They report up to 13× speedup relative to Jev for approximately 1,000 candidates in their measurements.
Again, this is a model-author benchmark claim rather than a universal performance guarantee.
Running CLM locally
The current project is open source and provides a local serving setup.
The basic architecture is:
clm-serve
│
CLM projection heads
│
▼
Qwen3-8B embeddings
│
▼
vLLM
The project provides the following installation pattern:
pip install contrastive-lm
vllm serve Qwen/Qwen3-8B \
--served-model-name qwen3-8b \
--runner pooling \
--max-model-len 2048 \
--port 8090
clm-serve
The CLM server downloads the approximately 75 MB reference head checkpoint on first use. The project notes that states longer than 2,048 tokens are truncated under the default configuration and that both serving limits must be increased for longer states.
Using the typed API
CLM intentionally exposes an interface similar to the System One concept used by Jev.
For example:
"""Demonstrate CLM typed decisions using Choice, Noul, and Score."""
from clm import CLMClient, Choice, Noul, Score
def main() -> None:
client = CLMClient()
result = client.system_one(
state=(
"Customer: my invoice was charged twice "
"and nobody answers the phone!"
),
questions={
"urgency": Noul(
instructions="Is this urgent?"
),
"department": Choice(
instructions="Which team should handle this?",
criteria={
"billing": "Charges, invoices, refunds",
"technical": "Bugs and outages",
},
),
"frustration": Score(
instructions="How frustrated is the customer?",
criteria=[
"Calm",
"Frustrated",
"Very angry",
],
),
},
)
print(result.answers["urgency"].noul)
print(result.answers["department"].choice)
print(result.answers["department"].probabilities)
print(result.answers["frustration"].score)
if __name__ == "__main__":
main()
This is not a separate generative model hidden behind a special prompt. The model is directly scoring the state against the supplied structured candidates.
Fine-tuning CLM
One of the practical advantages of the architecture is that the large Qwen backbone can remain frozen.
Only the projection heads need to be trained.
That means a downstream task can specialize:
generic CLM
↓
task-specific examples
↓
new projection head
↓
specialized verifier
The public project provides fine-tuning tooling for tasks including DeepSWE and typed decisions.
This is substantially cheaper than fully fine-tuning an 8B generative model.
CLM versus conventional embeddings
At first glance, CLM might look like:
"Isn't this just an embedding model?"
There is an important difference.
A normal embedding model might be trained to produce semantically meaningful vectors.
CLM specifically trains:
state embedding
↕
action embedding
so that compatibility between the two becomes predictive of the correct action.
The training distribution is therefore oriented toward decision behavior, not just generic semantic similarity.
The hard-negative stage makes this particularly important.
The objective is not simply:
"These texts mean similar things."
It is closer to:
"Given this state, which of these actions is actually appropriate?"
CLM versus Jev
The two models belong to the same broader System One category, but their mechanisms differ.
| Property | Jev | CLM-8B |
|---|---|---|
| Primary idea | Typed decision model | State/action compatibility |
| Public architecture | Proprietary | Frozen Qwen3-8B + two projection heads |
| Main training concept | RLCD | Contrastive learning / InfoNCE |
| Text generation | No | No |
| Structured decisions | Yes | Yes |
| Candidate ranking | Yes, through structured choices | Core capability |
| Cached candidate representations | Not the central public design | Central design |
| Open weights | No public weights described | Yes |
| Base model | Proprietary | Qwen3-8B |
| Fine-tuning | Managed service | Lightweight head fine-tuning |
Jev emphasizes the decision primitive and calibrated probability.
CLM emphasizes state/action representation and efficient ranking.
The distinction is subtle but important.
CLM's most interesting use case: AI agents
Consider an agent operating a computer.
Its current state might be:
Browser is open.
Search results are visible.
The user wants information about a specific paper.
Possible actions:
click result 1
click result 2
open new tab
scroll
search again
return to previous page
CLM can represent:
current state
and compare it against:
candidate actions
to determine which action best fits.
That becomes:

This is a much more natural formulation of action selection than asking a generative model to write the name of the tool it wants to invoke.
Limitations
CLM has several important limitations.
It cannot generate text
This is not a ChatGPT replacement.
You must provide candidate answers/actions for it to rank.
Probabilities are candidate-relative
If the candidate set is:
A
B
C
the probability distribution describes the model's preference among those candidates.
Adding or removing candidates changes the normalization.
So:
A = 0.90
does not necessarily mean:
90% probability that A is objectively correct.
It means that A received most of the probability mass among the candidates presented.
This matters enormously when using CLM as a verifier.
The released model is encoder-locked
The projection heads are designed for the Qwen3-8B embedding interface used by the checkpoint.
You cannot simply replace Qwen3 with another backbone and expect the heads to work unchanged.
Benchmark verifier results require fine-tuning
The reported DeepSWE and Terminal-Bench results use task-specific fine-tuned heads.
They should not be interpreted as the zero-shot performance of the base CLM-8B checkpoint.
Why CLM is scientifically interesting
The most interesting part of CLM is not simply that it is faster.
It changes the computational abstraction.
A conventional LLM asks:
CLM instead approximates something closer to:
where:
- (s) = current state
- (a) = candidate action
and implements that relationship through learned state/action representations.
This means a huge space of agent problems can potentially be reduced to:
encode state
↓
compare against candidate representations
↓
rank
That is an extremely different computational primitive from autoregressive generation.
Jev and CLM point toward a broader shift
The interesting thing about both systems is that neither starts by asking:
"How do we make an LLM generate better text?"
Instead, they ask:
"What if the model did not need to generate text at all?"
Jev's answer is:
typed probabilistic decisions
CLM's answer is:
state/action compatibility
And they suggest a broader architecture for future AI agents:

The generative model provides flexibility.
The decision model provides a controlled interface for software.
Final assessment
CLM-8B is interesting because it demonstrates that an 8-billion-parameter generative model can be repurposed into a much narrower but potentially much faster decision engine without training all 8 billion parameters for every downstream application.
Its most important ideas are:
frozen semantic backbone
+
separate state/action representations
+
contrastive training
+
hard negatives
+
candidate caching
+
ranking instead of generation
The result is not a better chatbot.
It is a different kind of model.
And perhaps the most interesting research question is what happens when this idea is extended beyond simple text actions:
text state
↓
multimodal state
↓
persistent state
↓
candidate actions
↓
parallel decisions
↓
verification
That direction is particularly relevant to agentic systems because the model can operate as a decision and verification layer around a generative model, rather than trying to replace the generator entirely.
The current CLM project also indicates a planned multimodal CLM-35B, which would extend the approach beyond text-only states. That is listed as an upcoming model rather than a currently released checkpoint, so it should be treated as a project announcement rather than an available model today.