Jaswanth1210 Claude Opus 4.7 commited on
Commit
6aebb94
·
1 Parent(s): 33bf00a

fix: drop BnB 4-bit, load attacker in plain bf16

Browse files

BitsAndBytes 4-bit pins lm_head (and other non-convert modules) to fp32
regardless of the dtype= kwarg, which collides with bf16 hidden states
inside GRPO's generate() path -> 'expected Float, found BFloat16' at
F.linear. The post-load cast loop did not stick reliably under
device_map='auto' + tied embeddings.

Qwen2.5-1.5B in bf16 is ~3 GB on A100 -- 4-bit was unnecessary.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

Files changed (1) hide show
  1. train/grpo_train.py +12 -17
train/grpo_train.py CHANGED
@@ -88,42 +88,37 @@ def _build_dataset(split: str = "train") -> Any:
88
 
89
 
90
  # ---------------------------------------------------------------------------
91
- # Model loading — standard transformers + PEFT (no Unsloth)
92
  #
93
  # Unsloth 2025.11.x patches TRL's GRPOTrainer with an incompatible
94
  # grpo_accumulated_loss signature, crashing at trainer.train(). Since the
95
  # reward evaluation (3.5 s/step) dominates, Unsloth's generation speedup
96
- # is not worth the breakage. Standard BitsAndBytes 4-bit is sufficient.
 
 
97
  # ---------------------------------------------------------------------------
98
 
99
  def _load_model_and_tokenizer(model_id: str, seed: int):
100
  import torch
101
- from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
102
  from peft import LoraConfig, get_peft_model
103
 
104
- logger.info("Loading %s via transformers + PEFT (4-bit LoRA) …", model_id)
105
- bnb = BitsAndBytesConfig(
106
- load_in_4bit=True,
107
- bnb_4bit_compute_dtype=torch.bfloat16,
108
- bnb_4bit_use_double_quant=True,
109
- bnb_4bit_quant_type="nf4",
110
- )
111
  tokenizer = AutoTokenizer.from_pretrained(model_id, trust_remote_code=True)
112
  if tokenizer.pad_token is None:
113
  tokenizer.pad_token = tokenizer.eos_token
114
 
115
  model = AutoModelForCausalLM.from_pretrained(
116
  model_id,
117
- quantization_config=bnb,
118
- dtype=torch.bfloat16,
119
  device_map="auto",
120
  trust_remote_code=True,
121
  )
122
- # Cast non-quantized params (lm_head, embeddings, norms) to bfloat16 so they
123
- # match the compute dtype during generation.
124
- for name, module in model.named_modules():
125
- if hasattr(module, "weight") and module.weight is not None and module.weight.dtype == torch.float32:
126
- module.to(torch.bfloat16)
127
 
128
  lora_cfg = LoraConfig(
129
  r=16,
 
88
 
89
 
90
  # ---------------------------------------------------------------------------
91
+ # Model loading — standard transformers + PEFT (no Unsloth, no BnB 4-bit)
92
  #
93
  # Unsloth 2025.11.x patches TRL's GRPOTrainer with an incompatible
94
  # grpo_accumulated_loss signature, crashing at trainer.train(). Since the
95
  # reward evaluation (3.5 s/step) dominates, Unsloth's generation speedup
96
+ # is not worth the breakage. BitsAndBytes 4-bit was tried but bnb pins
97
+ # lm_head to fp32 by default, causing dtype mismatches under bf16 compute
98
+ # in GRPO's generate() path — plain bf16 on A100 is simpler and faster.
99
  # ---------------------------------------------------------------------------
100
 
101
  def _load_model_and_tokenizer(model_id: str, seed: int):
102
  import torch
103
+ from transformers import AutoModelForCausalLM, AutoTokenizer
104
  from peft import LoraConfig, get_peft_model
105
 
106
+ # Plain bf16 (no 4-bit). Qwen2.5-1.5B is ~3 GB in bf16; trivial on A100.
107
+ # BnB 4-bit kept lm_head in fp32 (its modules_to_not_convert default) which
108
+ # caused F.linear dtype mismatches against the bf16 hidden states inside
109
+ # GRPO's generate() path, and post-hoc casting was unreliable under
110
+ # device_map="auto"+tied-embeddings. Dropping bnb removes the surface.
111
+ logger.info("Loading %s in bfloat16 + PEFT LoRA r=16 …", model_id)
 
112
  tokenizer = AutoTokenizer.from_pretrained(model_id, trust_remote_code=True)
113
  if tokenizer.pad_token is None:
114
  tokenizer.pad_token = tokenizer.eos_token
115
 
116
  model = AutoModelForCausalLM.from_pretrained(
117
  model_id,
118
+ torch_dtype=torch.bfloat16,
 
119
  device_map="auto",
120
  trust_remote_code=True,
121
  )
 
 
 
 
 
122
 
123
  lora_cfg = LoraConfig(
124
  r=16,