2323__all__ = ['CPUBone' ]
2424
2525
26+ _LOCAL_MBCONV_NORM_MODES = {
27+ # mode: (expand, depthwise, project)
28+ 'proj' : (False , False , True ),
29+ 'depth_proj' : (False , True , True ),
30+ 'all' : (True , True , True ),
31+ }
32+
33+
2634def remap_legacy_state_dict (state_dict : Dict [str , torch .Tensor ]) -> Dict [str , torch .Tensor ]:
2735 """Remap keys from original CPUBone checkpoints to the current model layout."""
2836 remapped = {}
@@ -369,8 +377,14 @@ def __init__(
369377 small_kernels : bool = False ,
370378 attn_upsample : str = 'transpose' ,
371379 drop_path : float = 0. ,
380+ local_mbconv_norm : str = 'proj' ,
372381 ):
373382 super ().__init__ ()
383+ if local_mbconv_norm not in _LOCAL_MBCONV_NORM_MODES :
384+ raise ValueError (
385+ f'Invalid local_mbconv_norm={ local_mbconv_norm !r} ; '
386+ f'expected one of { tuple (_LOCAL_MBCONV_NORM_MODES )} .'
387+ )
374388 att_kernel = 5 if att_stride > 1 else 3
375389
376390 block = ConvAttention (
@@ -405,14 +419,18 @@ def __init__(
405419 act_layer = (act_layer , None ),
406420 )
407421 else :
422+ norm_mask = _LOCAL_MBCONV_NORM_MODES [local_mbconv_norm ]
423+ local_norms = tuple (norm_layer if enabled else None for enabled in norm_mask )
424+ # A convolution bias is redundant whenever normalization follows it.
425+ local_biases = tuple (not enabled for enabled in norm_mask )
408426 local_module = MBConv (
409427 in_channels = in_channels ,
410428 out_channels = in_channels ,
411429 expand_ratio = expand_ratio ,
412430 expand_groups = expand_groups ,
413- use_bias = ( True , True , False ) ,
431+ use_bias = local_biases ,
414432 kernel_size = 2 if small_kernels else 3 ,
415- norm_layer = ( None , None , norm_layer ) ,
433+ norm_layer = local_norms ,
416434 act_layer = (act_layer , act_layer , None ),
417435 )
418436
@@ -496,6 +514,7 @@ def __init__(
496514 expand_groups : int = 1 ,
497515 small_kernels : bool = False ,
498516 attn_upsample : str = 'transpose' ,
517+ local_mbconv_norm : str = 'proj' ,
499518 ) -> None :
500519 """
501520 Args:
@@ -522,6 +541,9 @@ def __init__(
522541 local conv branch).
523542 attn_upsample: Upsampling mode after strided attention, 'transpose' (learned
524543 ConvTranspose2d) or 'nearest' (parameter-free nearest-neighbor).
544+ local_mbconv_norm: Normalization placement in unfused CPUBoneBlock local MBConvs;
545+ one of 'proj', 'depth_proj', or 'all'. Convolution biases are disabled wherever
546+ normalization is enabled.
525547
526548 The ablation flags of the original implementation map onto these args as follows:
527549 `fastit=True` → `fused_conv=True, fused_downsample=True, attn_mlp_ratio=4` (adding
@@ -533,6 +555,11 @@ def __init__(
533555 super ().__init__ ()
534556 assert global_pool in ("" , "avg" ), "CPUBone only supports average or disabled pooling"
535557 assert attn_upsample in ('transpose' , 'nearest' )
558+ if local_mbconv_norm not in _LOCAL_MBCONV_NORM_MODES :
559+ raise ValueError (
560+ f'Invalid local_mbconv_norm={ local_mbconv_norm !r} ; '
561+ f'expected one of { tuple (_LOCAL_MBCONV_NORM_MODES )} .'
562+ )
536563 num_stages = len (width_list ) - 1
537564 if downsample_expand_ratios is None :
538565 downsample_expand_ratios = (expand_ratio ,) * num_stages
@@ -554,6 +581,7 @@ def __init__(
554581 self .expand_groups = expand_groups
555582 self .small_kernels = small_kernels
556583 self .attn_upsample = attn_upsample
584+ self .local_mbconv_norm = local_mbconv_norm
557585
558586 # stochastic depth: linear ramp of drop rates across all blocks (downsample blocks have no
559587 # shortcut and ignore theirs)
@@ -681,6 +709,7 @@ def _build_attention_stage(
681709 small_kernels = self .small_kernels ,
682710 attn_upsample = self .attn_upsample ,
683711 drop_path = dpr [i ],
712+ local_mbconv_norm = self .local_mbconv_norm ,
684713 )
685714 )
686715 return blocks , in_channels
@@ -842,6 +871,8 @@ def _cfg(url: str = "", **kwargs: Any) -> Dict[str, Any]:
842871 "cpubone_nano.in1k" : _cfg (hf_hub_id = "Kaeruu/CPUBone" , hf_hub_filename = "cpubone_nano.safetensors" ),
843872 "cpubone_b0.in1k" : _cfg (hf_hub_id = "Kaeruu/CPUBone" , hf_hub_filename = "cpubone_b0.safetensors" ),
844873 "cpubone_b1.in1k" : _cfg (hf_hub_id = "Kaeruu/CPUBone" , hf_hub_filename = "cpubone_b1.safetensors" ),
874+ "cpubone_b1_dwnorm.untrained" : _cfg (),
875+ "cpubone_b1_allnorm.untrained" : _cfg (),
845876 "cpubone_b2.in1k" : _cfg (hf_hub_id = "Kaeruu/CPUBone" , hf_hub_filename = "cpubone_b2.safetensors" ),
846877 "cpubone_b3.in1k" : _cfg (hf_hub_id = "Kaeruu/CPUBone" , hf_hub_filename = "cpubone_b3.safetensors" ),
847878})
@@ -894,9 +925,8 @@ def cpubone_b0(pretrained: bool = False, **kwargs: Any) -> CPUBone:
894925 return _create_cpubone ("cpubone_b0" , pretrained = pretrained , ** dict (model_args , ** kwargs ))
895926
896927
897- @register_model
898- def cpubone_b1 (pretrained : bool = False , ** kwargs : Any ) -> CPUBone :
899- model_args = dict (
928+ def _cpubone_b1_args (local_mbconv_norm : str = 'proj' ) -> Dict [str , Any ]:
929+ return dict (
900930 width_list = [16 , 32 , 64 , 128 , 256 ],
901931 depth_list = [0 , 1 , 1 , 5 , 5 ],
902932 fused_conv = True ,
@@ -906,10 +936,28 @@ def cpubone_b1(pretrained: bool = False, **kwargs: Any) -> CPUBone:
906936 expand_groups = 2 ,
907937 small_kernels = True ,
908938 attn_upsample = "nearest" ,
939+ local_mbconv_norm = local_mbconv_norm ,
909940 )
941+
942+
943+ @register_model
944+ def cpubone_b1 (pretrained : bool = False , ** kwargs : Any ) -> CPUBone :
945+ model_args = _cpubone_b1_args ()
910946 return _create_cpubone ("cpubone_b1" , pretrained = pretrained , ** dict (model_args , ** kwargs ))
911947
912948
949+ @register_model
950+ def cpubone_b1_dwnorm (pretrained : bool = False , ** kwargs : Any ) -> CPUBone :
951+ model_args = _cpubone_b1_args (local_mbconv_norm = 'depth_proj' )
952+ return _create_cpubone ("cpubone_b1_dwnorm" , pretrained = pretrained , ** dict (model_args , ** kwargs ))
953+
954+
955+ @register_model
956+ def cpubone_b1_allnorm (pretrained : bool = False , ** kwargs : Any ) -> CPUBone :
957+ model_args = _cpubone_b1_args (local_mbconv_norm = 'all' )
958+ return _create_cpubone ("cpubone_b1_allnorm" , pretrained = pretrained , ** dict (model_args , ** kwargs ))
959+
960+
913961@register_model
914962def cpubone_b2 (pretrained : bool = False , ** kwargs : Any ) -> CPUBone :
915963 model_args = dict (
0 commit comments