1pub fn map_tensor_name(hf_name: &str) -> Option<String> {
19 if hf_name == "cls_tokens" {
20 return Some("cls_tokens".into());
21 }
22 if let Some(rest) = hf_name.strip_prefix("cell_embedder.") {
23 return map_cell(rest);
24 }
25 for (prefix, stack) in [
26 ("col_embedder_2.", "colenc2"),
27 ("col_embedder.", "colenc1"),
28 ("row_interactor_2.", "rowenc2"),
29 ("row_interactor.", "rowenc1"),
30 ] {
31 if let Some(rest) = hf_name.strip_prefix(prefix) {
32 return map_stack(stack, rest, prefix.starts_with("col"));
33 }
34 }
35 if let Some(rest) = hf_name.strip_prefix("icl_predictor.") {
36 return map_icl(rest);
37 }
38 None
39}
40
41fn map_cell(rest: &str) -> Option<String> {
42 match rest {
43 "fourier_frequencies" => Some("cell.fourier_freq".into()),
44 "fourier_frequencies_cat" => Some("cell.fourier_freq_cat".into()),
45 "in_linear.weight" => Some("cell.in_linear.weight".into()),
46 "in_linear.bias" => Some("cell.in_linear.bias".into()),
47 "in_linear_cat.weight" => Some("cell.in_linear_cat.weight".into()),
48 "in_linear_cat.bias" => Some("cell.in_linear_cat.bias".into()),
49 "y_embedder_lookup.weight" => Some("cell.y_embed.weight".into()),
51 _ => {
52 rest.strip_prefix("y_embedder_lookup.layers.")
54 .and_then(|r| map_mlp_leaf("cell.y_embed", r))
55 }
56 }
57}
58
59fn map_mlp_leaf(base: &str, rest: &str) -> Option<String> {
61 let dot = rest.find('.')?;
62 let idx: usize = rest[..dot].parse().ok()?;
63 let field = &rest[dot + 1..];
64 if field != "weight" && field != "bias" {
65 return None;
66 }
67 Some(format!("{base}.mlp.{idx}.{field}"))
68}
69
70fn map_stack(stack: &str, rest: &str, is_col: bool) -> Option<String> {
71 if is_col {
72 if let Some(r) = rest.strip_prefix("tf_col.blocks.") {
73 return map_block(stack, r, true);
74 }
75 match rest {
76 "out_w.weight" => Some(format!("{stack}.out_w.weight")),
77 "out_w.bias" => Some(format!("{stack}.out_w.bias")),
78 "ln_w.weight" => Some(format!("{stack}.out_norm.weight")),
79 _ => None,
80 }
81 } else {
82 if rest == "tf_row.rope.freqs" {
83 return Some(format!("{stack}.rope_freqs"));
84 }
85 if let Some(r) = rest.strip_prefix("tf_row.blocks.") {
86 return map_block(stack, r, false);
87 }
88 if rest == "out_ln.weight" {
89 return Some(format!("{stack}.out_norm.weight"));
90 }
91 None
92 }
93}
94
95fn map_block(stack: &str, rest: &str, has_mab: bool) -> Option<String> {
98 let dot = rest.find('.')?;
99 let n: usize = rest[..dot].parse().ok()?;
100 let suffix = &rest[dot + 1..];
101 let blk_prefix = format!("{stack}.blk.{n}");
102
103 if has_mab {
104 if suffix == "ind_vectors" {
105 return Some(format!("{blk_prefix}.ind_vectors"));
106 }
107 for mab in ["mab1", "mab2"] {
108 if let Some(leaf) = suffix.strip_prefix(&format!("{mab}.")) {
109 let mapped = map_mab_leaf(leaf)?;
110 return Some(format!("{blk_prefix}.{mab}.{mapped}"));
111 }
112 }
113 None
114 } else {
115 let mapped = map_mab_leaf(suffix)?;
116 Some(format!("{blk_prefix}.{mapped}"))
117 }
118}
119
120fn map_mab_leaf(leaf: &str) -> Option<String> {
123 if let Some(r) = leaf.strip_prefix("attn.") {
124 return match r {
125 "q_proj.weight" => Some("attn_q.weight".into()),
126 "q_proj.bias" => Some("attn_q.bias".into()),
127 "k_proj.weight" => Some("attn_k.weight".into()),
128 "k_proj.bias" => Some("attn_k.bias".into()),
129 "v_proj.weight" => Some("attn_v.weight".into()),
130 "v_proj.bias" => Some("attn_v.bias".into()),
131 "out_proj.weight" => Some("attn_o.weight".into()),
132 "out_proj.bias" => Some("attn_o.bias".into()),
133 "query_ln.weight" => Some("q_norm.weight".into()),
134 "key_ln.weight" => Some("k_norm.weight".into()),
135 "per_dim_scale" => Some("per_dim_scale".into()),
136 _ => None,
137 };
138 }
139 match leaf {
140 "pre_attn_ln.weight" => Some("pre_attn_norm.weight".into()),
141 "post_attn_ln.weight" => Some("post_attn_norm.weight".into()),
142 "pre_ff_ln.weight" => Some("pre_ff_norm.weight".into()),
143 "post_ff_ln.weight" => Some("post_ff_norm.weight".into()),
144 "linear1.weight" => Some("ffn_up.weight".into()),
145 "linear1.bias" => Some("ffn_up.bias".into()),
146 "linear1_gate.weight" => Some("ffn_gate.weight".into()),
147 "linear1_gate.bias" => Some("ffn_gate.bias".into()),
148 "linear2.weight" => Some("ffn_down.weight".into()),
149 "linear2.bias" => Some("ffn_down.bias".into()),
150 _ => None,
151 }
152}
153
154fn map_icl(rest: &str) -> Option<String> {
155 if let Some(r) = rest.strip_prefix("tf_icl.blocks.") {
156 return map_block("icl", r, false);
157 }
158 match rest {
159 "ln.weight" => return Some("icl.out_norm.weight".into()),
160 "y_encoder.projection.weight" => return Some("icl.y_encoder.projection.weight".into()),
161 "y_encoder.projection.bias" => return Some("icl.y_encoder.projection.bias".into()),
162 _ => {}
163 }
164 if let Some(r) = rest.strip_prefix("y_encoder.layers.") {
165 return map_mlp_leaf("icl.y_encoder", r);
166 }
167 if let Some(r) = rest.strip_prefix("decoder.layers.") {
168 return map_mlp_leaf("icl.decoder", r);
169 }
170 None
171}
172
173#[cfg(test)]
174mod tests {
175 use super::*;
176
177 #[test]
178 fn test_cls_tokens() {
179 assert_eq!(map_tensor_name("cls_tokens"), Some("cls_tokens".into()));
180 }
181
182 #[test]
183 fn test_cell_embedder_fourier() {
184 assert_eq!(
185 map_tensor_name("cell_embedder.fourier_frequencies"),
186 Some("cell.fourier_freq".into())
187 );
188 assert_eq!(
189 map_tensor_name("cell_embedder.fourier_frequencies_cat"),
190 Some("cell.fourier_freq_cat".into())
191 );
192 }
193
194 #[test]
195 fn test_cell_embedder_in_linear() {
196 assert_eq!(
197 map_tensor_name("cell_embedder.in_linear.weight"),
198 Some("cell.in_linear.weight".into())
199 );
200 assert_eq!(
201 map_tensor_name("cell_embedder.in_linear_cat.bias"),
202 Some("cell.in_linear_cat.bias".into())
203 );
204 }
205
206 #[test]
207 fn test_cell_embedder_y_embed_classification() {
208 assert_eq!(
209 map_tensor_name("cell_embedder.y_embedder_lookup.weight"),
210 Some("cell.y_embed.weight".into())
211 );
212 }
213
214 #[test]
215 fn test_cell_embedder_y_embed_regression_mlp() {
216 assert_eq!(
217 map_tensor_name("cell_embedder.y_embedder_lookup.layers.0.weight"),
218 Some("cell.y_embed.mlp.0.weight".into())
219 );
220 assert_eq!(
221 map_tensor_name("cell_embedder.y_embedder_lookup.layers.1.bias"),
222 Some("cell.y_embed.mlp.1.bias".into())
223 );
224 }
225
226 #[test]
227 fn test_col_stack_ind_vectors_and_mab() {
228 assert_eq!(
229 map_tensor_name("col_embedder.tf_col.blocks.0.ind_vectors"),
230 Some("colenc1.blk.0.ind_vectors".into())
231 );
232 assert_eq!(
233 map_tensor_name("col_embedder_2.tf_col.blocks.2.mab2.attn.q_proj.weight"),
234 Some("colenc2.blk.2.mab2.attn_q.weight".into())
235 );
236 assert_eq!(
237 map_tensor_name("col_embedder.tf_col.blocks.1.mab1.attn.per_dim_scale"),
238 Some("colenc1.blk.1.mab1.per_dim_scale".into())
239 );
240 assert_eq!(
241 map_tensor_name("col_embedder.tf_col.blocks.0.mab1.pre_ff_ln.weight"),
242 Some("colenc1.blk.0.mab1.pre_ff_norm.weight".into())
243 );
244 assert_eq!(
245 map_tensor_name("col_embedder.tf_col.blocks.0.mab2.linear1_gate.weight"),
246 Some("colenc1.blk.0.mab2.ffn_gate.weight".into())
247 );
248 }
249
250 #[test]
251 fn test_col_stack_out_projection() {
252 assert_eq!(
253 map_tensor_name("col_embedder.out_w.weight"),
254 Some("colenc1.out_w.weight".into())
255 );
256 assert_eq!(
257 map_tensor_name("col_embedder_2.ln_w.weight"),
258 Some("colenc2.out_norm.weight".into())
259 );
260 }
261
262 #[test]
263 fn test_row_stack_rope_and_block() {
264 assert_eq!(
265 map_tensor_name("row_interactor.tf_row.rope.freqs"),
266 Some("rowenc1.rope_freqs".into())
267 );
268 assert_eq!(
269 map_tensor_name("row_interactor_2.tf_row.blocks.2.attn.out_proj.bias"),
270 Some("rowenc2.blk.2.attn_o.bias".into())
271 );
272 assert_eq!(
273 map_tensor_name("row_interactor.tf_row.blocks.0.post_attn_ln.weight"),
274 Some("rowenc1.blk.0.post_attn_norm.weight".into())
275 );
276 assert_eq!(
277 map_tensor_name("row_interactor.out_ln.weight"),
278 Some("rowenc1.out_norm.weight".into())
279 );
280 }
281
282 #[test]
283 fn test_icl_block() {
284 assert_eq!(
285 map_tensor_name("icl_predictor.tf_icl.blocks.23.linear2.weight"),
286 Some("icl.blk.23.ffn_down.weight".into())
287 );
288 assert_eq!(
289 map_tensor_name("icl_predictor.ln.weight"),
290 Some("icl.out_norm.weight".into())
291 );
292 }
293
294 #[test]
295 fn test_icl_y_encoder_classification() {
296 assert_eq!(
297 map_tensor_name("icl_predictor.y_encoder.projection.weight"),
298 Some("icl.y_encoder.projection.weight".into())
299 );
300 }
301
302 #[test]
303 fn test_icl_y_encoder_regression_and_decoder() {
304 assert_eq!(
305 map_tensor_name("icl_predictor.y_encoder.layers.0.weight"),
306 Some("icl.y_encoder.mlp.0.weight".into())
307 );
308 assert_eq!(
309 map_tensor_name("icl_predictor.decoder.layers.1.bias"),
310 Some("icl.decoder.mlp.1.bias".into())
311 );
312 }
313
314 #[test]
315 fn test_unrecognized_returns_none() {
316 assert_eq!(map_tensor_name("some.random.optimizer.state"), None);
317 }
318}