@@ -230,6 +230,26 @@ def _per_layer_embedding_block_size(embedding_dim: int, group_size: int) -> int:
230230 return group_size
231231
232232
233+ def _per_layer_embedding_quantization (config : Gemma4Config ) -> tuple [int , int , bool ] | None :
234+ """Return split per-layer embedding quantization as (bits, group_size, symmetric)."""
235+ bits = getattr (config , "per_layer_embedding_bits" , None )
236+ if bits is None :
237+ quantization_config = getattr (config , "quantization" , None )
238+ if quantization_config is None or not getattr (
239+ quantization_config , "quantize_embeddings" , False
240+ ):
241+ return None
242+ bits = quantization_config .bits
243+ group_size = quantization_config .group_size
244+ symmetric = quantization_config .sym
245+ else :
246+ group_size = getattr (config , "per_layer_embedding_group_size" , 32 )
247+ symmetric = getattr (config , "per_layer_embedding_sym" , False )
248+ if bits not in (4 , 8 ):
249+ raise ValueError (f"quantize_embeddings requires bits=4 or bits=8, got { bits } " )
250+ return bits , group_size , symmetric
251+
252+
233253def _dtype_safe_compress (
234254 op : OpBuilder , data : ir .Value , condition : ir .Value , * , axis : int
235255) -> ir .Value :
@@ -1830,25 +1850,20 @@ def __init__(self, config: Gemma4Config):
18301850 # 256 MiB limit; ~128 MiB each vs ~4.7 GB fused).
18311851 # Only the table actually called in forward() is realized as an
18321852 # ONNX initializer, so the unused one adds no graph weight.
1833- qc = getattr (config , "quantization" , None )
1834- if (
1835- qc is not None
1836- and getattr (qc , "quantize_embeddings" , False )
1837- and config .split_per_layer_embedding
1838- ):
1839- block_size = _per_layer_embedding_block_size (
1840- self ._per_layer_dim , qc .group_size
1841- )
1853+ per_layer_quant = _per_layer_embedding_quantization (config )
1854+ if per_layer_quant is not None and config .split_per_layer_embedding :
1855+ bits , group_size , symmetric = per_layer_quant
1856+ block_size = _per_layer_embedding_block_size (self ._per_layer_dim , group_size )
18421857 self .embed_tokens_per_layer_split = nn .ModuleList (
18431858 [
18441859 QuantizedScaledWordEmbedding (
18451860 vocab_per_layer ,
18461861 self ._per_layer_dim ,
18471862 config .pad_token_id ,
18481863 embed_scale = float (self ._per_layer_dim ** 0.5 ),
1849- bits = qc . bits ,
1864+ bits = bits ,
18501865 block_size = block_size ,
1851- has_zero_point = not qc . sym ,
1866+ has_zero_point = not symmetric ,
18521867 )
18531868 for _ in range (self ._num_layers )
18541869 ]
@@ -2402,24 +2417,18 @@ def preprocess_weights(
24022417 f"got { fused .shape [1 ]} "
24032418 )
24042419 chunks = fused .chunk (num_layers , dim = 1 )
2405- qc = getattr (self .config , "quantization" , None )
2406- quantize_per_layer = qc is not None and getattr (
2407- qc , "quantize_embeddings" , False
2408- )
2409- if quantize_per_layer :
2410- if qc .bits not in (4 , 8 ):
2411- raise ValueError (
2412- f"quantize_embeddings requires bits=4 or bits=8, got { qc .bits } "
2413- )
2420+ per_layer_quant = _per_layer_embedding_quantization (self .config )
2421+ if per_layer_quant is not None :
2422+ bits , group_size , symmetric = per_layer_quant
24142423 from mobius ._weight_utils import quantize_embedding_rtn
24152424
2416- block_size = _per_layer_embedding_block_size (per_layer_dim , qc . group_size )
2425+ block_size = _per_layer_embedding_block_size (per_layer_dim , group_size )
24172426 for i , chunk in enumerate (chunks ):
24182427 qweight , scales , zero_points = quantize_embedding_rtn (
24192428 chunk .contiguous (),
2420- bits = qc . bits ,
2429+ bits = bits ,
24212430 block_size = block_size ,
2422- symmetric = qc . sym ,
2431+ symmetric = symmetric ,
24232432 )
24242433 state_dict [f"model.embed_tokens_per_layer_split.{ i } .qweight" ] = qweight
24252434 state_dict [f"model.embed_tokens_per_layer_split.{ i } .scales" ] = scales
@@ -3229,24 +3238,18 @@ def preprocess_weights(
32293238 f"got { fused .shape [1 ]} "
32303239 )
32313240 chunks = fused .chunk (num_layers , dim = 1 )
3232- qc = getattr (self .config , "quantization" , None )
3233- quantize_per_layer = qc is not None and getattr (
3234- qc , "quantize_embeddings" , False
3235- )
3236- if quantize_per_layer :
3237- if qc .bits not in (4 , 8 ):
3238- raise ValueError (
3239- f"quantize_embeddings requires bits=4 or bits=8, got { qc .bits } "
3240- )
3241+ per_layer_quant = _per_layer_embedding_quantization (self .config )
3242+ if per_layer_quant is not None :
3243+ bits , group_size , symmetric = per_layer_quant
32413244 from mobius ._weight_utils import quantize_embedding_rtn
32423245
3243- block_size = _per_layer_embedding_block_size (per_layer_dim , qc . group_size )
3246+ block_size = _per_layer_embedding_block_size (per_layer_dim , group_size )
32443247 for i , chunk in enumerate (chunks ):
32453248 qweight , scales , zero_points = quantize_embedding_rtn (
32463249 chunk .contiguous (),
3247- bits = qc . bits ,
3250+ bits = bits ,
32483251 block_size = block_size ,
3249- symmetric = qc . sym ,
3252+ symmetric = symmetric ,
32503253 )
32513254 renamed [f"decoder.model.embed_tokens_per_layer_split.{ i } .qweight" ] = (
32523255 qweight
0 commit comments