Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs/ATTENTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Valid grouped-head shapes require the query heads to map consistently onto KV gr
For an attention input $z$, the normalized shared KV latent is

$$
c_t=\operatorname{RMSNorm}_{KV}(W_{DKV}z_t)\in\mathbb R^{d_c}.
c_t=\mathrm{RMSNorm}_{KV}(W_{DKV}z_t)\in\mathbb R^{d_c}.
\tag{A1}
$$

Expand All @@ -55,9 +55,9 @@ RMSNorm denotes root mean square normalization. The projections for a query head
$$
\begin{aligned}
q^C_{t,h}&=N_Q^C(W_{QC,h}z_t)\in\mathbb R^{d_n},\\
q^R_{t,h}&=\operatorname{RoPE}_t\!\left(N_Q^R(W_{QR,h}z_t)\right)\in\mathbb R^{d_r},\\
q^R_{t,h}&=\mathrm{RoPE}_t\left(N_Q^R(W_{QR,h}z_t)\right)\in\mathbb R^{d_r},\\
k^C_{s,m}&=W_{KC,m}c_s\in\mathbb R^{d_n},\\
k^R_{s,m}&=\operatorname{RoPE}_s(W_{KR,m}c_s)\in\mathbb R^{d_r},\\
k^R_{s,m}&=\mathrm{RoPE}_s(W_{KR,m}c_s)\in\mathbb R^{d_r},\\
v_{s,m}&=W_{V,m}c_s\in\mathbb R^{d_h}.
\end{aligned}
\tag{A2}
Expand Down Expand Up @@ -96,7 +96,7 @@ $$
Causal, padding and document masks define the allowed positions. At evaluation, or with attention dropout disabled, softmax and value aggregation are

$$
a_{t,s,h}=\operatorname{softmax}_{s}(s_{t,s,h}+M_{t,s}),\qquad
a_{t,s,h}=\mathrm{softmax}_{s}(s_{t,s,h}+M_{t,s}),\qquad
u_{t,h}=\sum_sa_{t,s,h}v_{s,m(h)}.
\tag{A4}
$$
Expand Down
4 changes: 2 additions & 2 deletions docs/CLUSTER_LOCALITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ $$
The current training path obtains $M$ from `training_clusters(config)`. It splits expert IDs into contiguous, near-equal groups. The cluster count is the explicit positive `cluster_locality_clusters`, or otherwise

$$
N_c=\operatorname{clip}_{[1,E]}\!\left(\left\lceil\frac{E}{2k}\right\rceil\right).
N_c=\mathrm{clip}_{[1,E]}\left(\left\lceil\frac{E}{2k}\right\rceil\right).
$$

There is no implemented `clusters.partition_json` training field in this snapshot. A cluster manifest used by storage is a separate object. [Partition implementation](../chronos/expert_clusters.py#L28).
Expand Down Expand Up @@ -174,7 +174,7 @@ The implementation uses mean total variation from the iteration mean:

$$
L_{\mathrm{iter}}
=\operatorname{mean}_{b,t,g,r}
=\mathrm{mean}_{b,t,g,r}
\left[\frac12\sum_c|q_{b,t,g,r,c}-\bar q_{b,t,g,c}|\right],
$$

Expand Down
12 changes: 6 additions & 6 deletions docs/KERNEL_ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ The input operation is a lookup. The output operation is a linear projection:

$$
h_{b,t}^{(0)}=W_{\mathrm{in}}[x_{b,t}],\qquad
z_{b,t}=W_{\mathrm{out}}\operatorname{RMSNorm}(h_{b,t}^{\mathrm{coda}}),
z_{b,t}=W_{\mathrm{out}}\mathrm{RMSNorm}(h_{b,t}^{\mathrm{coda}}),
\quad W_{\mathrm{in}},W_{\mathrm{out}}\in\mathbb R^{V\times d}.
\tag{K.1}
$$
Expand Down Expand Up @@ -86,13 +86,13 @@ Physical parity includes the prelude offset. Recurrent group $g$ occupies physic
For the default SiLU activation, a bias-free SwiGLU expert with intermediate width $m$ is

$$
E(h)=W_d\bigl[\operatorname{SiLU}(W_g h)\odot(W_u h)\bigr].
E(h)=W_d\bigl[\mathrm{SiLU}(W_g h)\odot(W_u h)\bigr].
\tag{K.3}
$$

Its three matrices contain $3dm$ weights. Dense and expert intermediate widths are separate configuration fields. There is no general requirement that either equals $4d$.

For routed expert probabilities $p=\operatorname{softmax}_{\mathrm{FP32}}(W_r h)$, let $I$ be the selected top-$k$ set. The normal fully available MoE path is
For routed expert probabilities $p=\mathrm{softmax}_{\mathrm{FP32}}(W_r h)$, let $I$ be the selected top-$k$ set. The normal fully available MoE path is

$$
M(h)=\sum_{i\in I}a_iE_i(h)+\bar S(h),\qquad
Expand All @@ -110,8 +110,8 @@ The implemented contracted step is indexed by recurrent group and iteration. It

$$
\begin{aligned}
h^*&=h+e_r+u_g,\\
\Phi_{r,g}(h)&=h+\alpha_g\left[F_{P+g}(h^*;\mathcal K_g^{(0)})-h\right].
h^{\ast}&=h+e_r+u_g,\\
\Phi_{r,g}(h)&=h+\alpha_g\left[F_{P+g}(h^{\ast};\mathcal K_g^{(0)})-h\right].
\end{aligned}
\tag{K.5}
$$
Expand Down Expand Up @@ -202,7 +202,7 @@ in bounded decode. A shared prefill view can be longer than the retained cache.
Define expert-to-cluster membership $A_{i,c}\in\{0,1\}$. Aggregate routing probabilities over tokens and dispatches within a stream unit $w$:

$$
p(c\mid w)=\sum_i A_{i,c}\,\operatorname{mean}_{(t,v)\in w}p_{t,v,i}.
p(c\mid w)=\sum_i A_{i,c}\,\mathrm{mean}_{(t,v)\in w}p_{t,v,i}.
\tag{K.9}
$$

Expand Down
8 changes: 6 additions & 2 deletions docs/LAZY_EXPERTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,12 @@ Torch replaces evicted experts with `LazyExpertPlaceholder` modules. Before disc
`AsyncPrefetcher` owns a `queue.Queue`, not a deadline-priority queue. Each entry is a batch of expert IDs. `CacheManager` sets its capacity to

$$
Q_{\mathrm{batches}}=\max\!\left(1,\,2\,\mathrm{prefetch\_depth}\right).
Q_{\mathrm{batches}}=\max\left(1,\;2d\right).
\tag{3}
$$

Here $d$ denotes the `prefetch_depth` configuration value.

The default `prefetch_depth=2` therefore gives four request batches through this manager. The standalone prefetcher constructor has its own default of eight batches. Neither value means a fixed number of outstanding SSD system calls. [Manager construction](../chronos/runtime/cache_manager.py#L35), [queue implementation](../chronos/io/async_prefetcher.py#L47)

```mermaid
Expand Down Expand Up @@ -194,11 +196,13 @@ The code neither zeros missing terms nor renormalizes the surviving experts afte

$$
K_{\mathrm{RAM}}=\max\left(1,\left\lfloor
\frac{\mathrm{ram\_budget\_mb}\,2^{20}}{p_{\mathrm{page}}}
\frac{B\cdot 2^{20}}{p_{\mathrm{page}}}
\right\rfloor\right).
\tag{8}
$$

Here $B$ denotes the `ram_budget_mb` value in megabytes and $p_{\mathrm{page}}$ is the on-disk page size in bytes.

A requested budget smaller than one page cannot create a sub-page cache. These hard counts coexist with backend safety heuristics and dynamic pressure handling. They are not a bound on the entire process, KV cache, activations or transient cluster materialization. [Budget conversion](../chronos/io/expert_store.py#L31)

The MLX allocator cache limit, `min(physical RAM / 8, 16 GiB)`, bounds reclaimable Metal buffer cache. It is **not** the resident-expert budget. Live arrays remain active memory. [Allocator limit](../chronos/mlx/memory.py#L1)
Expand Down
4 changes: 2 additions & 2 deletions docs/LONG_CONTEXT.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ For batch $B$, query heads $H_q$ and head width $d_h$, the leading full-causal a
For the implemented SWA block span, a corresponding work estimate is

$$
O\!\left(\frac{T}{c}\,BH_q\,c(W+c)d_h\right)
=O\!\left(BH_qT(W+c)d_h\right).
O\left(\frac{T}{c}\,BH_q\,c(W+c)d_h\right)
=O\left(BH_qT(W+c)d_h\right).
\tag{7}
$$

Expand Down
18 changes: 10 additions & 8 deletions docs/LOOKAHEAD.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ That architectural separation does not make prediction errors harmless. A wrong
Use $t$ for token position, $\delta$ for future token offset, $g$ for a recurrent physical group and $r$ for recurrent iteration. The future horizon is

$$
\delta\in\{1,\ldots,K\},\qquad K=\texttt{lookahead\_steps}.
\delta\in\{1,\ldots,K\}.
$$

Here $K$ denotes the `lookahead_steps` configuration value.

The head additionally emits slot zero. Its output is

$$
Expand Down Expand Up @@ -58,7 +60,7 @@ flowchart TB
Let $d$ be backbone width and $m=\max(1,\lfloor d/4\rfloor)$. The current head is

$$
u=\operatorname{SiLU}(W_1h),\qquad z=W_2u,\qquad Q=\operatorname{softmax}_E(\operatorname{reshape}(z)),
u=\mathrm{SiLU}(W_1h),\qquad z=W_2u,\qquad Q=\mathrm{softmax}_E(\mathrm{reshape}(z)),
$$

with bias-free matrices
Expand Down Expand Up @@ -111,12 +113,12 @@ The teacher is a **soft future routing distribution**, not just hard expert IDs.

The accepted string is `"iterations"`, not `"all"`. Averaging probabilities across recurrent calls is not taking a union of their hard selected IDs. The separate future-union objective below concerns **token offsets**. [Scope validation](../chronos/model/config.py#L301), [teacher sources](../chronos/trainer/loss_mixin.py#L101).

When predictions lack a group axis, teacher probabilities are averaged across physical layers. With a group axis, the trainer selects physical recurrent layers $P$ through $P+G-1$. In either case, the teacher is stop-gradient. Denote that aligned distribution by $\operatorname{sg}(P_{b,t,g,e})$.
When predictions lack a group axis, teacher probabilities are averaged across physical layers. With a group axis, the trainer selects physical recurrent layers $P$ through $P+G-1$. In either case, the teacher is stop-gradient. Denote that aligned distribution by $\mathrm{sg}(P_{b,t,g,e})$.

Input detachment is a different decision:

$$
h_{\mathrm{LA}}=\begin{cases}\operatorname{sg}(h),&\text{input detach enabled},\\h,&\text{otherwise}.\end{cases}
h_{\mathrm{LA}}=\begin{cases}\mathrm{sg}(h),&\text{input detach enabled},\\h,&\text{otherwise}.\end{cases}
$$

`lookahead_input_detach` defaults to false. MLX applies the switch at the head call. In the reviewed Torch call sites, the flag is not consulted: changing it alone does not create a stopped-gradient input there. This is an implementation-parity boundary, not a feature that documentation can assume works identically. [Config](../chronos/model/config.py#L166), [MLX switch](../chronos/mlx/model.py#L269), [Torch call](../chronos/model/model_chronos.py#L492).
Expand Down Expand Up @@ -145,14 +147,14 @@ For valid future offset $\delta$, align prediction at $t$ with routing at $t+\de

$$
\ell_{b,t,g}^{(\delta)}
=-\sum_e\operatorname{sg}(P_{b,t+\delta,g,e})\log Q_{b,t,\delta,g,e}.
=-\sum_e\mathrm{sg}(P_{b,t+\delta,g,e})\log Q_{b,t,\delta,g,e}.
$$

The loss averages valid token/group examples within each offset, then averages available offsets:

$$
L_{\mathrm{LA}}=\frac1{|\mathcal D|}\sum_{\delta\in\mathcal D}
\operatorname{mean}_{b,t,g:\,t+\delta<T}\ell_{b,t,g}^{(\delta)}.
\mathrm{mean}_{b,t,g:\,t+\delta<T}\ell_{b,t,g}^{(\delta)}.
$$

Offsets with no valid pair are skipped. Expanding cross-entropy gives
Expand All @@ -171,7 +173,7 @@ Let $I_{b,t+\delta,g}$ be the teacher's future top-k set. The auxiliary hit-mass

$$
M_{b,t,g}^{(\delta)}=\sum_{e\in I_{b,t+\delta,g}}Q_{b,t,\delta,g,e},\qquad
L_{\mathrm{hit}}=\operatorname{mean}\left[-\log\frac{M^{(\delta)}}{k}\right].
L_{\mathrm{hit}}=\mathrm{mean}\left[-\log\frac{M^{(\delta)}}{k}\right].
$$

The division by $k$ is a constant for the selected setting. It gives a uniform predictor the same reference loss $\log E$ across top-k choices. It does not alter the derivative with respect to $Q$. A prediction can place most of its mass on only part of the teacher set, so this is a differentiable **coverage proxy**, not a theorem guaranteeing exact top-k recall. [Hit-mass implementation](../chronos/model/temporal_loss.py#L316).
Expand All @@ -188,7 +190,7 @@ $$
The implemented proxy is

$$
L_{\mathrm{union}}=\operatorname{mean}\left[
L_{\mathrm{union}}=\mathrm{mean}\left[
-\log\frac{\sum_eU_e\widehat Q_e}{\sum_eU_e}\right].
$$

Expand Down
4 changes: 2 additions & 2 deletions docs/MOE_ROUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ $$

The router linear layer has **no bias**. Both Torch and MLX cast the router scores to FP32 before softmax; this is a numerical policy, not evidence of a measured latency benefit. Torch uses `torch.topk`; MLX uses `argpartition` and gathers the selected scores. The separate sorting of dispatch rows groups tokens by expert; it should not be confused with the top-k selection algorithm. [Torch selection](../chronos/model/moe_chronos.py#L138), [MLX selection](../chronos/mlx/moe.py#L233).

Write $I(h)=\operatorname{TopK}(g,k)$. If `norm_topk_prob=True`,
Write $I(h)=\mathrm{TopK}(g,k)$. If `norm_topk_prob=True`,

$$
a_i=\frac{g_i}{\sum_{j\in I}g_j+\epsilon},\quad i\in I,
Expand Down Expand Up @@ -53,7 +53,7 @@ flowchart TB
With the default `hidden_act="silu"`, an expert is a SwiGLU map:

$$
E_i(h)=W_{d,i}\left[\operatorname{SiLU}(W_{g,i}h)
E_i(h)=W_{d,i}\left[\mathrm{SiLU}(W_{g,i}h)
\odot W_{u,i}h\right],
$$

Expand Down
4 changes: 2 additions & 2 deletions docs/OVERVIEW.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ The backbone contains prelude blocks, recurrent physical groups and coda blocks.
The actual group update conditions the input on iteration and group embeddings:

$$
h^*=h+e_r+u_g,\qquad
h'=h+\alpha_g\bigl[F_{P+g}(h^*;\mathcal K)-h\bigr].
h^{\ast}=h+e_r+u_g,\qquad
h'=h+\alpha_g\bigl[F_{P+g}(h^{\ast};\mathcal K)-h\bigr].
$$

The full block $F$ includes attention and an MLP with two internal residual additions. The outer interpolation is a separate controller operation. A small step size can damp an update; it does not by itself prove contraction or convergence.
Expand Down
4 changes: 2 additions & 2 deletions docs/SPEC_DECODE.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ The supported shallow/full cache layout must be depth independent. `shared_first
At proposal position $i$, let $d_i$ be the shallow proposal and $p_i$ the full-depth distribution conditioned on the committed prefix and all previously accepted proposals. Greedy verification accepts while

$$
d_i=\operatorname*{arg\,max}_{v}p_i(v).
d_i=\mathop{\mathrm{arg\,max}}\limits_{v}p_i(v).
\tag{1}
$$

Expand All @@ -85,7 +85,7 @@ For sampled generation, let $q(v)$ be the normalized draft distribution and $p(v
A token $v\sim q$ is accepted with probability

$$
a(v)=\min\!\left(1,\frac{p(v)}{q(v)}\right).
a(v)=\min\left(1,\frac{p(v)}{q(v)}\right).
\tag{2}
$$

Expand Down
28 changes: 14 additions & 14 deletions docs/THEORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ A full pre-normalization block is the map $F_\ell$, not merely its residual incr

$$
\begin{aligned}
a &= h + A_\ell\!\left(N_{\ell,1}(h);\mathcal K_\ell\right),\\
a &= h + A_\ell\left(N_{\ell,1}(h);\mathcal K_\ell\right),\\
F_\ell(h;\mathcal K_\ell)
&=a+M_\ell\!\left(N_{\ell,2}(a)\right).
&=a+M_\ell\left(N_{\ell,2}(a)\right).
\end{aligned}
\tag{T1}
$$
Expand Down Expand Up @@ -81,7 +81,7 @@ The implemented map depends on $e_r$, the group, cached context and sometimes ro
The helper [recommended_dt_init](../chronos/model/recurrent.py#L17) returns

$$
\alpha_0(R)=\min\!\left(0.5,\frac{2}{R}\right).
\alpha_0(R)=\min\left(0.5,\frac{2}{R}\right).
\tag{T6}
$$

Expand Down Expand Up @@ -116,10 +116,10 @@ $$
\tag{T9}
$$

For $\mu\ne1$, this requires $\operatorname{Re}\mu<1$ and
For $\mu\ne1$, this requires $\mathrm{Re}\mu<1$ and

$$
0<\alpha<\frac{2(1-\operatorname{Re}\mu)}{|\mu-1|^2}.
0<\alpha<\frac{2(1-\mathrm{Re}\mu)}{|\mu-1|^2}.
\tag{T10}
$$

Expand All @@ -142,7 +142,7 @@ $$

The derivative is positive for finite $\theta_g$ in real arithmetic. It can become very small near saturation, and finite precision can round it to zero. This removes the explicit dead region of a hard clamp; it does not eliminate vanishing gradients.

The clamp option computes $\alpha_g=\operatorname{clip}(\theta_g,\alpha_{\min},\alpha_{\max})$. Parameters outside the interval have zero derivative. The MLX implementation uses an explicit inclusive-boundary rule to match Torch; see [RecurrentControllerMLX.contract](../chronos/mlx/recurrent.py#L54). Monitoring should include raw $\theta_g$, effective $\alpha_g$ and gradients, not only effective step size.
The clamp option computes $\alpha_g=\mathrm{clip}(\theta_g,\alpha_{\min},\alpha_{\max})$. Parameters outside the interval have zero derivative. The MLX implementation uses an explicit inclusive-boundary rule to match Torch; see [RecurrentControllerMLX.contract](../chronos/mlx/recurrent.py#L54). Monitoring should include raw $\theta_g$, effective $\alpha_g$ and gradients, not only effective step size.

## 3. Why loop order changes the computation

Expand Down Expand Up @@ -188,7 +188,7 @@ Their leading difference is $\epsilon^2(J_ba-J_ab)$. This explains why order can

## 4. Sparse experts and routing-locality objectives

For a normalized MLP input $z$, the router computes $p(z)=\operatorname{softmax}(W_gz)$ in FP32. Let $\mathcal I_k(z)$ be the selected expert IDs. If `norm_topk_prob=True`,
For a normalized MLP input $z$, the router computes $p(z)=\mathrm{softmax}(W_gz)$ in FP32. Let $\mathcal I_k(z)$ be the selected expert IDs. If `norm_topk_prob=True`,

$$
\widehat p_i(z)=\frac{p_i(z)}{\sum_{j\in\mathcal I_k(z)}p_j(z)},\qquad
Expand All @@ -202,16 +202,16 @@ Equation T14 assumes $S_s>0$; omit the shared branch when no shared experts are
Let $A_{ic}$ be the fixed expert-to-cluster membership matrix. Aggregate routing mass across tokens and all dispatches in a window $w$:

$$
p_w(c)=\operatorname{mean}_{(b,t,v)\in w}\sum_i p_{b,t,v,i}A_{ic}.
p_w(c)=\mathrm{mean}_{(b,t,v)\in w}\sum_i p_{b,t,v,i}A_{ic}.
\tag{T15}
$$

For more than one cluster, the implemented window objective is

$$
\mathcal L_{\mathrm{cluster}}
=1-\frac{H(\overline p)-\operatorname{mean}_wH(p_w)}{\log N_c},
\qquad \overline p=\operatorname{mean}_wp_w.
=1-\frac{H(\overline p)-\mathrm{mean}_wH(p_w)}{\log N_c},
\qquad \overline p=\mathrm{mean}_wp_w.
\tag{T16}
$$

Expand Down Expand Up @@ -247,13 +247,13 @@ For a detached teacher distribution $P$, the basic supervision is soft-target cr

$$
\mathcal L_{\mathrm{LA}}
=\operatorname{mean}_{j\in\mathcal J}
\left[-\operatorname{mean}_{b,t,g}
=\mathrm{mean}_{j\in\mathcal J}
\left[-\mathrm{mean}_{b,t,g}
\sum_iP_{b,t+j,g,i}\log Q_{b,t,j,g,i}\right].
\tag{T18}
$$

Only horizons $\mathcal J$ with available token pairs contribute. The implementation clamps predicted probabilities below at $10^{-9}$ before taking logs. For fixed detached $P$, soft-target cross-entropy equals $\operatorname{KL}(P\|Q)+H(P)$. The teacher entropy has no gradient through this loss, so its optimization direction matches forward KL.
Only horizons $\mathcal J$ with available token pairs contribute. The implementation clamps predicted probabilities below at $10^{-9}$ before taking logs. For fixed detached $P$, soft-target cross-entropy equals $\mathrm{KL}(P\|Q)+H(P)$. The teacher entropy has no gradient through this loss, so its optimization direction matches forward KL.

Padding and document-boundary handling depend on the active training path. This loss differs from classifying one cluster ID. Expert-to-page mapping occurs later in the runtime. Code: [lookahead_supervision_loss](../chronos/model/temporal_loss.py#L259).

Expand Down Expand Up @@ -282,7 +282,7 @@ $$
D_{\mathrm{used}}=\sum_jjw_j,
\qquad
\mathcal L_{\mathrm{ponder}}=
\operatorname{mean}\max(D_{\mathrm{used}}-1,0).
\mathrm{mean}\max(D_{\mathrm{used}}-1,0).
\tag{T20}
$$

Expand Down
4 changes: 2 additions & 2 deletions docs/vllm_integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ flowchart LR
For MLA, the adapter must define whether it stores latents and rotary keys or expanded K/V, and how the attention kernel reconstructs the same scores. For SWA, it must preserve the moving window and absolute end index. For speculation, append and rollback must commute with $\Phi$:

$$
\Phi(\operatorname{truncate}(C,n))
=\operatorname{truncate}_{\mathrm{engine}}(\Phi(C),n).
\Phi(\mathrm{truncate}(C,n))
=\mathrm{truncate}_{\mathrm{engine}}(\Phi(C),n).
\tag{3}
$$

Expand Down
Loading