LiLiCorr: Correlating Parallel Drafts
Independent slot predictions can form an incoherent draft; LiLiCorr scores candidate transitions in context in one pass, then greedily selects a coherent sequence.
Read the paper ↗What it is
- Candidate lattice Keep a shortlist of possible tokens at each draft position, then score links between choices at neighboring positions.
- Incoming and outgoing vectors Each candidate gets two context-aware representations: one for what can lead into it and one for what can follow it.
- Greedy selection After scoring links, choose a draft from left to right by picking the best next candidate for the choice already made.
Why it matters
Independent predictions can be individually plausible but clash when assembled. LiLiCorr adds context-aware links among shortlisted choices in one network pass, avoiding a separate network run at every draft position while keeping final selection simple.
Before getting into the machinery, here is the idea: predict several possible tokens for each draft position, then score how well neighboring choices fit together. LiLiCorr computes those relationships in one network pass and picks a path through them from left to right. That matters because independent best guesses can make a locally plausible but incoherent block.
- Coherence: A drafter can get each position's likely token roughly right and still combine those tokens into a bad sequence. The canonical example is choosing a subject, verb, and modifier independently: each may be plausible, while the resulting sentence is not. This is the marginals problem; the example is just an intuition, not a claim that language coherence is only about adjacent words.
- Cost: A direct score for every possible block grows combinatorially with block length. Iteratively fixing mistakes costs more drafter passes, while asking the target to rerank paths spends the computation speculative decoding is meant to save. So the real question is not just how to make each slot better, but how to connect choices cheaply.
The basic move is to keep a shortlist at each slot and give each candidate a way to describe what should come before it and what should come after it. Think of a candidate as a notebook entry with an incoming and outgoing edge: a good neighboring pair is one whose edges line up. That notebook analogy stops being literal because these are learned vectors, not stored words. The system measures their alignment with cosine similarity: in plain terms, it asks whether the earlier choice's outgoing direction matches the later choice's incoming direction.
This is why the vectors need context. A static lookup table for token pairs would give the same pair the same score wherever it appeared. LiLiCorr instead computes representations for candidates in the surrounding candidate set, so a link can reflect the draft context. The paper describes training these vectors to align for consecutive ground-truth tokens and to separate competing pairings. Intuitively, the model learns which neighboring choices belong together, rather than merely memorizing that two token identities often co-occur.
So how do you get those context-sensitive links without running a network separately for every position? LiLiCorr produces the vectors for all shortlisted candidates and slots in one network pass. Once those are available, adjacent links can be scored together as matrix operations. The network work is parallel; only the final choice is sequential.
At selection time, start at the first slot, then choose the candidate at the next slot that best matches the choice already committed. Repeat left to right. That is cheap and easy to follow, but it is greedy: an early choice is not revisited if it later turns out to limit the path. Overall, I like the clean separation between parallel scoring and a visible selection rule, though the greedy walk is a real limitation. The open question is whether local links are enough to produce a good whole block in the cases that matter.
Read the deep dive
Why People Wanted It
A parallel drafter can predict several positions at once, but choosing the most likely token at each position independently can combine locally plausible choices into a sequence that does not fit together. The challenge is that a block of positions over a vocabulary of size has possible sequences: scoring every complete block directly is not practical. Iterative correction asks for more network passes; tree reranking shifts work to the target model. So the real question is whether you can recover useful relationships between neighboring choices without explicitly modeling every whole sequence.
The Core Move
LiLiCorr gives every shortlisted candidate a context-aware incoming and outgoing vector, scores adjacent candidates by cosine similarity, and computes those vectors for all slots and candidates in one pass. Then a left-to-right greedy walk chooses a path through the candidate lattice.
For candidate at one slot and candidate at the next, the compatibility is
The score asks whether the first candidate's outgoing representation aligns with the next candidate's incoming representation.
Why Adjacent Compatibility Helps Recover a Joint Draft
Now the version for readers who want more of the machinery: the lattice keeps the top- candidates at each position, and adjacent-pair scores provide a tractable local structure over those choices. If is the candidate chosen at slot , a path can be scored by adding its neighboring compatibility scores, rather than assigning a separate score to every possible full block:
This sum captures pairwise consistency, not an exact representation of the full joint distribution. The distinction matters: a sequence may have good adjacent links without every longer-range dependency being represented. What can a local score tell us about a whole draft?
Why Contextual Incoming and Outgoing Vectors Matter
Here is the part that gets technical: the vectors are produced for each candidate in the context of the other candidates around it, not just from the identities of the two tokens in a pair. The outgoing vector represents how a candidate can connect forward; the incoming vector represents what can connect into it. Their cosine similarity scores the directed neighboring relationship.
During training, consecutive ground-truth tokens are used to align their outgoing and incoming vectors, while competing pairings are separated. This makes compatibility depend on the draft context in which candidates occur. A token pair is therefore not assigned one context-free score for every appearance. How can the system compute these context-dependent vectors without a separate pass for each slot?
Why One Pass Leaves Only a Greedy Walk Sequential
Now for the computation tradeoff: one bidirectional network pass emits incoming and outgoing vectors for candidates across all slots. Every adjacent candidate pair can then be scored with matrix operations, in parallel; the remaining sequential step is the selection walk, not another network evaluation.
At inference, the walk proceeds left to right. Given the already committed candidate at the previous slot, it chooses the candidate at the current slot with the best connecting score. This is greedy selection, not global search over all paths: a locally strongest next link can constrain later choices. What do we gain by keeping that final decision simple, and what does greedy choice give up?
Minimal Causal Code
This loop shows the selection rule after the candidate vectors and pair scores have already been computed. It is deliberately plain: vector creation and scoring are outside the loop, while the state update is visible.
# pair_score[i, a, b] scores candidate b at slot i+1
# against candidate a at slot i.
chosen = [start_candidate]
for i in range(num_slots - 1):
previous = chosen[-1]
next_candidate = pair_score[i, previous].argmax().item()
chosen.append(next_candidate)
What You Gain, and What You Lose
You gain context-aware compatibility across shortlisted candidates, with all candidate vectors and adjacent-pair scores computed in one network pass. The final left-to-right selection adds no network weights or passes. This avoids materializing the full block distribution and avoids a network evaluation at every draft position.
You lose global path optimization: the greedy walk commits based on its current predecessor and does not reconsider earlier choices. The score also expresses adjacent compatibility rather than the complete joint distribution over the block. And the one-pass claim concerns scoring the candidate lattice; it does not mean every stage of speculative decoding disappears. LiLiCorr is a way to make parallel proposals cohere better, not a guarantee that every selected block is globally best.
LiLiCorr turns parallel candidates into a context-aware lattice in one pass, then commits to a path one neighboring link at a time.