Skip to content

Commit 6a81fa9

Browse files
eaglstunclaude
andcommitted
Fix Lion to use decoupled weight decay in the CUDA 32-bit kernel
Mirror of the merged upstream fix (bitsandbytes-foundation#1993): kOptimizer32bit1State folded weight decay into the gradient (coupled L2) for every optimizer including Lion, which corrupts Lion's sign update. Exclude LION from the coupled fold and apply decoupled decay (p *= 1 - lr*wd) in the LION branch, matching the 8-bit kernel and the cpu/default backends. The default backend + test_lion32bit_weight_decay are already on this fork's main; this adds the remaining CUDA kernel piece. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 5e7ff4e commit 6a81fa9

1 file changed

Lines changed: 9 additions & 1 deletion

File tree

csrc/kernels.cu

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -858,7 +858,11 @@ __launch_bounds__(TH, 1) __global__ void kOptimizer32bit1State(
858858
#pragma unroll 4
859859
for (unsigned int j = 0; j < NUM_PER_THREAD; j++) {
860860
g_vals[j] = gnorm_scale * ((float)g_vals[j]);
861-
if (weight_decay > 0.0f)
861+
// Coupled (L2) weight decay folds decay into the gradient. Correct for
862+
// MOMENTUM/RMSPROP/ADAGRAD, but NOT for LION, which uses decoupled
863+
// (AdamW-style) decay applied to the param directly (see the LION branch
864+
// below and Chen et al. 2023). This matches the CUDA 8-bit blockwise kernel.
865+
if (weight_decay > 0.0f && OPTIMIZER != LION)
862866
g_vals[j] = (float)g_vals[j] + (((float)p_vals[j]) * weight_decay);
863867
}
864868

@@ -875,6 +879,10 @@ __launch_bounds__(TH, 1) __global__ void kOptimizer32bit1State(
875879
p_vals[j] = ((float)p_vals[j]) + update_scale * (-lr * (s1_vals[j]));
876880
break;
877881
case LION:
882+
// Decoupled weight decay: shrink the param directly, outside the
883+
// sign update (Chen et al. 2023), matching the 8-bit blockwise kernel.
884+
if (weight_decay > 0.0f)
885+
p_vals[j] = ((float)p_vals[j]) * (1.0f - lr * weight_decay);
878886
p_vals[j] =
879887
((float)p_vals[j]) -
880888
update_scale * (lr * sgn(((float)s1_vals[j]) * beta1 + ((1.0f - beta1) * ((float)g_vals[j]))));

0 commit comments

Comments
 (0)