@@ -358,8 +358,11 @@ def layer_fn(carry, scanned_vars):
358358 new_carry = layer_out [0 ] if isinstance (layer_out , tuple ) else layer_out
359359 # Avoid returning and stacking read-only parameters inside the scan body.
360360 # This prevents huge unnecessary memory allocation.
361- _ , _ , updated_state = nnx .split (layer , nnx .Param , ...)
362- return new_carry , updated_state
361+ if self .config .enable_nnx_scan_oom_fix :
362+ _ , _ , updated_state = nnx .split (layer , nnx .Param , ...)
363+ return new_carry , updated_state
364+ else :
365+ return new_carry , nnx .state (layer )
363366
364367 final_carry , scanned_state = jax .lax .scan (layer_fn , inputs , (params , state ))
365368
@@ -868,20 +871,40 @@ def _create_scanned_layers(
868871 layer_graphdef , _ , _ = nnx .split (ref_layer , nnx .Param , ...)
869872 del ref_layer
870873
871- def scan_body (carry , rng_state_slice ):
872- layer_rngs = nnx .merge (rngs_graphdef , rng_state_slice )
873- layer = decoder_layer_class (
874- config = self .config ,
875- mesh = self .mesh ,
876- quant = self .quant ,
877- model_mode = self .model_mode ,
878- rngs = layer_rngs ,
879- ** layer_kwargs ,
880- )
881- _ , params , rest = nnx .split (layer , nnx .Param , ...)
882- return carry , (params , rest )
874+ if self .config .enable_nnx_scan_oom_fix :
875+ params_list = []
876+ rest_list = []
877+ for i in range (length ):
878+ layer_rng_state = jax .tree .map (lambda x : x [i ], rngs_state )
879+ layer_rngs = nnx .merge (rngs_graphdef , layer_rng_state )
880+ layer = decoder_layer_class (
881+ config = self .config ,
882+ mesh = self .mesh ,
883+ quant = self .quant ,
884+ model_mode = self .model_mode ,
885+ rngs = layer_rngs ,
886+ ** layer_kwargs ,
887+ )
888+ _ , params , rest = nnx .split (layer , nnx .Param , ...)
889+ params_list .append (params )
890+ rest_list .append (rest )
891+ stacked_params = jax .tree .map (lambda * args : jnp .stack (args ), * params_list )
892+ stacked_rest = jax .tree .map (lambda * args : jnp .stack (args ), * rest_list )
893+ else :
894+ def scan_body (carry , rng_state_slice ):
895+ layer_rngs = nnx .merge (rngs_graphdef , rng_state_slice )
896+ layer = decoder_layer_class (
897+ config = self .config ,
898+ mesh = self .mesh ,
899+ quant = self .quant ,
900+ model_mode = self .model_mode ,
901+ rngs = layer_rngs ,
902+ ** layer_kwargs ,
903+ )
904+ _ , params , rest = nnx .split (layer , nnx .Param , ...)
905+ return carry , (params , rest )
883906
884- _ , (stacked_params , stacked_rest ) = jax .lax .scan (scan_body , None , rngs_state )
907+ _ , (stacked_params , stacked_rest ) = jax .lax .scan (scan_body , None , rngs_state )
885908
886909 if scan_axis != 0 :
887910 stacked_params = jax .tree .map (lambda x : jnp .moveaxis (x , scan_axis , 0 ), stacked_params )
@@ -1037,8 +1060,11 @@ def layer_fn(carry, scanned_vars):
10371060 else :
10381061 # Avoid returning and stacking read-only parameters inside the scan body.
10391062 # This prevents huge unnecessary memory allocation.
1040- _ , _ , updated_state = nnx .split (layer , nnx .Param , ...)
1041- new_current_state = updated_state
1063+ if self .config .enable_nnx_scan_oom_fix :
1064+ _ , _ , updated_state = nnx .split (layer , nnx .Param , ...)
1065+ new_current_state = updated_state
1066+ else :
1067+ new_current_state = nnx .state (layer )
10421068
10431069 if use_kv :
10441070 return new_carry , (new_current_state , updated_kv )
0 commit comments