szxllm commited on
Commit
afd1085
·
verified ·
1 Parent(s): e576d4e

Update dcpo_train.py

Browse files
Files changed (1) hide show
  1. dcpo_train.py +12 -46
dcpo_train.py CHANGED
@@ -17,7 +17,6 @@ warnings.filterwarnings("ignore", category=FutureWarning)
17
  from model import MultiModalDenseTransformer
18
  from dcpo import DCPOTrainer
19
 
20
- # ================= DDP 设置 =================
21
  def setup_distributed():
22
  if "RANK" in os.environ and "WORLD_SIZE" in os.environ:
23
  dist.init_process_group(backend="nccl")
@@ -38,7 +37,6 @@ IS_MAIN = RANK == 0
38
  logger = logging.getLogger(__name__)
39
  logger.setLevel(logging.INFO if IS_MAIN else logging.WARNING)
40
 
41
- # ================= 数据集 =================
42
  class MathDataset(Dataset):
43
  def __init__(self, path):
44
  self.data = []
@@ -59,9 +57,7 @@ def math_collate(batch):
59
  'ground_truth': [item['ground_truth'] for item in batch]
60
  }
61
 
62
- # ================= 主函数 =================
63
  def main():
64
- # ------------------ 配置区域 ------------------
65
  CONFIG = {
66
  'sft_checkpoint': '/root/checkpoints/dcpo_posttrain_round3/step_1200.pt',
67
  'data_path': '/root/dataset/r1_zero_math.jsonl',
@@ -87,15 +83,12 @@ def main():
87
  'gradient_accumulation_steps': 8,
88
  'inner_batch_size': 4,
89
 
90
- # ========== 关键新增1: 奖励验证器配置 ==========
91
- 'use_reference_comparison': True, # 是否使用参考推理对比
92
- 'use_progressive_reward': False, # 是否使用渐进式奖励(实验性)
93
- 'phase1_steps': 2000, # 渐进式阶段1(宽松格式)
94
- 'phase2_steps': 4000, # 渐进式阶段2(中等格式)
95
  }
96
- # ---------------------------------------------
97
 
98
- # 初始化日志文件 Handler
99
  file_handler = None
100
  if IS_MAIN:
101
  os.makedirs(CONFIG['save_dir'], exist_ok=True)
@@ -105,31 +98,17 @@ def main():
105
  file_handler = logging.FileHandler(log_file, encoding='utf-8')
106
  file_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
107
  logger.addHandler(file_handler)
108
-
109
- # 将配置写入日志文件
110
- logger.info(f"DCPO Configuration: {json.dumps(CONFIG, indent=2)}")
111
-
112
- # ========== 关键新增2: 记录使用的验证器类型 ==========
113
- if CONFIG['use_progressive_reward']:
114
- logger.info(f"使用渐进式奖励验证器:")
115
- logger.info(f" - 阶段1 (0-{CONFIG['phase1_steps']}): 宽松格式")
116
- logger.info(f" - 阶段2 ({CONFIG['phase1_steps']}-{CONFIG['phase2_steps']}): 中等格式")
117
- logger.info(f" - 阶段3 ({CONFIG['phase2_steps']}+): 完整要求")
118
- else:
119
- logger.info(f"使用标准改进版验证器 (reference_comparison={CONFIG['use_reference_comparison']})")
120
-
121
  metrics_file = os.path.join(CONFIG['save_dir'], "metrics.jsonl")
122
  if not os.path.exists(metrics_file):
123
  with open(metrics_file, 'w', encoding='utf-8') as f:
124
  pass
125
-
126
- # 1. 加载 Tokenizer
127
  tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-7B-Instruct", trust_remote_code=True)
128
  if tokenizer.pad_token is None:
129
  tokenizer.pad_token = tokenizer.eos_token
130
  tokenizer.pad_token_id = tokenizer.eos_token_id
131
-
132
- # 2. 初始化模型
133
  def create_model():
134
  return MultiModalDenseTransformer(
135
  model_dim=CONFIG['model_dim'],
@@ -152,8 +131,6 @@ def main():
152
  if WORLD_SIZE > 1:
153
  actor = DDP(actor, device_ids=[LOCAL_RANK], output_device=LOCAL_RANK)
154
 
155
- # 3. 初始化 Trainer
156
- # ========== 关键新增3: 传入新的验证器参数 ==========
157
  trainer = DCPOTrainer(
158
  actor_model=actor,
159
  ref_model=ref,
@@ -166,14 +143,12 @@ def main():
166
  use_amp=True,
167
  gradient_accumulation_steps=CONFIG['gradient_accumulation_steps'],
168
  inner_batch_size=CONFIG['inner_batch_size'],
169
- # 新增参数
170
  use_reference_comparison=CONFIG['use_reference_comparison'],
171
  use_progressive_reward=CONFIG['use_progressive_reward'],
172
  phase1_steps=CONFIG['phase1_steps'],
173
  phase2_steps=CONFIG['phase2_steps']
174
  )
175
-
176
- # 4. 恢复状态
177
  start_step = 0
178
  samples_seen = 0
179
 
@@ -203,7 +178,6 @@ def main():
203
  start_step = checkpoint.get('step', 0) + 1
204
  samples_seen = checkpoint.get('samples_seen', start_step * CONFIG['batch_size'] * WORLD_SIZE)
205
 
206
- # ========== 关键新增4: 恢复时更新步数(用于渐进式奖励) ==========
207
  if CONFIG['use_progressive_reward']:
208
  trainer.update_step(start_step)
209
  if IS_MAIN:
@@ -228,7 +202,6 @@ def main():
228
  gc.collect()
229
  torch.cuda.empty_cache()
230
 
231
- # 5. Dataloader
232
  dataset = MathDataset(CONFIG['data_path'])
233
  if WORLD_SIZE > 1:
234
  sampler = torch.utils.data.DistributedSampler(
@@ -245,7 +218,6 @@ def main():
245
  if IS_MAIN:
246
  print(f"Starting Training from step {start_step}")
247
 
248
- # 6. Dataloader 指针恢复
249
  if sampler:
250
  epoch = start_step // len(dataloader)
251
  sampler.set_epoch(epoch)
@@ -267,7 +239,6 @@ def main():
267
  data_iter = iter(dataloader)
268
  next(data_iter)
269
 
270
- # 7. 训练循环
271
  progress_bar = tqdm(
272
  range(start_step, CONFIG['max_steps']),
273
  disable=not IS_MAIN,
@@ -282,7 +253,6 @@ def main():
282
 
283
  for step in progress_bar:
284
  try:
285
- # ========== 关键新增5: 更新训练步数(用于渐进式奖励) ==========
286
  if CONFIG['use_progressive_reward']:
287
  trainer.update_step(step)
288
 
@@ -297,7 +267,7 @@ def main():
297
 
298
  samples_seen += CONFIG['batch_size'] * WORLD_SIZE
299
 
300
- # 1. 生成 + SAS
301
  experience = trainer.generate_and_prepare(
302
  batch,
303
  max_gen_len=CONFIG['max_gen_len']
@@ -307,13 +277,11 @@ def main():
307
  if running_reward == 0: running_reward = step_reward
308
  else: running_reward = 0.95 * running_reward + 0.05 * step_reward
309
 
310
- # 2. 训练步骤
311
  loss = trainer.train_step(experience)
312
 
313
- # 状态栏缩写
314
  status_dict = {"Rw": f"{running_reward:.2f}"}
315
-
316
- # ========== 关键新增6: 添加阶段信息显示(如果使用渐进式) ==========
317
  if CONFIG['use_progressive_reward'] and hasattr(trainer.math_verifier, 'current_phase'):
318
  status_dict["Ph"] = f"{trainer.math_verifier.current_phase}"
319
 
@@ -334,7 +302,6 @@ def main():
334
  "timestamp": datetime.now().isoformat()
335
  }
336
 
337
- # ========== 关键新增7: 记录渐进式阶段信息 ==========
338
  if CONFIG['use_progressive_reward'] and hasattr(trainer.math_verifier, 'current_phase'):
339
  metrics_data['reward_phase'] = trainer.math_verifier.current_phase
340
 
@@ -353,8 +320,7 @@ def main():
353
  status_dict["St"] = "Acc"
354
 
355
  progress_bar.set_description(f"{' '.join([f'{k}:{v}' for k,v in status_dict.items()])}")
356
-
357
- # 保存逻辑
358
  is_accum_boundary = (len(trainer.experience_buffer) == 0)
359
 
360
  if step > 0 and step % CONFIG['save_interval'] == 0 and IS_MAIN:
 
17
  from model import MultiModalDenseTransformer
18
  from dcpo import DCPOTrainer
19
 
 
20
  def setup_distributed():
21
  if "RANK" in os.environ and "WORLD_SIZE" in os.environ:
22
  dist.init_process_group(backend="nccl")
 
37
  logger = logging.getLogger(__name__)
38
  logger.setLevel(logging.INFO if IS_MAIN else logging.WARNING)
39
 
 
40
  class MathDataset(Dataset):
41
  def __init__(self, path):
42
  self.data = []
 
57
  'ground_truth': [item['ground_truth'] for item in batch]
58
  }
59
 
 
60
  def main():
 
61
  CONFIG = {
62
  'sft_checkpoint': '/root/checkpoints/dcpo_posttrain_round3/step_1200.pt',
63
  'data_path': '/root/dataset/r1_zero_math.jsonl',
 
83
  'gradient_accumulation_steps': 8,
84
  'inner_batch_size': 4,
85
 
86
+ 'use_reference_comparison': True,
87
+ 'use_progressive_reward': False,
88
+ 'phase1_steps': 2000,
89
+ 'phase2_steps': 4000,
 
90
  }
 
91
 
 
92
  file_handler = None
93
  if IS_MAIN:
94
  os.makedirs(CONFIG['save_dir'], exist_ok=True)
 
98
  file_handler = logging.FileHandler(log_file, encoding='utf-8')
99
  file_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
100
  logger.addHandler(file_handler)
101
+
 
 
 
 
 
 
 
 
 
 
 
 
102
  metrics_file = os.path.join(CONFIG['save_dir'], "metrics.jsonl")
103
  if not os.path.exists(metrics_file):
104
  with open(metrics_file, 'w', encoding='utf-8') as f:
105
  pass
106
+
 
107
  tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-7B-Instruct", trust_remote_code=True)
108
  if tokenizer.pad_token is None:
109
  tokenizer.pad_token = tokenizer.eos_token
110
  tokenizer.pad_token_id = tokenizer.eos_token_id
111
+
 
112
  def create_model():
113
  return MultiModalDenseTransformer(
114
  model_dim=CONFIG['model_dim'],
 
131
  if WORLD_SIZE > 1:
132
  actor = DDP(actor, device_ids=[LOCAL_RANK], output_device=LOCAL_RANK)
133
 
 
 
134
  trainer = DCPOTrainer(
135
  actor_model=actor,
136
  ref_model=ref,
 
143
  use_amp=True,
144
  gradient_accumulation_steps=CONFIG['gradient_accumulation_steps'],
145
  inner_batch_size=CONFIG['inner_batch_size'],
 
146
  use_reference_comparison=CONFIG['use_reference_comparison'],
147
  use_progressive_reward=CONFIG['use_progressive_reward'],
148
  phase1_steps=CONFIG['phase1_steps'],
149
  phase2_steps=CONFIG['phase2_steps']
150
  )
151
+
 
152
  start_step = 0
153
  samples_seen = 0
154
 
 
178
  start_step = checkpoint.get('step', 0) + 1
179
  samples_seen = checkpoint.get('samples_seen', start_step * CONFIG['batch_size'] * WORLD_SIZE)
180
 
 
181
  if CONFIG['use_progressive_reward']:
182
  trainer.update_step(start_step)
183
  if IS_MAIN:
 
202
  gc.collect()
203
  torch.cuda.empty_cache()
204
 
 
205
  dataset = MathDataset(CONFIG['data_path'])
206
  if WORLD_SIZE > 1:
207
  sampler = torch.utils.data.DistributedSampler(
 
218
  if IS_MAIN:
219
  print(f"Starting Training from step {start_step}")
220
 
 
221
  if sampler:
222
  epoch = start_step // len(dataloader)
223
  sampler.set_epoch(epoch)
 
239
  data_iter = iter(dataloader)
240
  next(data_iter)
241
 
 
242
  progress_bar = tqdm(
243
  range(start_step, CONFIG['max_steps']),
244
  disable=not IS_MAIN,
 
253
 
254
  for step in progress_bar:
255
  try:
 
256
  if CONFIG['use_progressive_reward']:
257
  trainer.update_step(step)
258
 
 
267
 
268
  samples_seen += CONFIG['batch_size'] * WORLD_SIZE
269
 
270
+ # 生成 + SAS
271
  experience = trainer.generate_and_prepare(
272
  batch,
273
  max_gen_len=CONFIG['max_gen_len']
 
277
  if running_reward == 0: running_reward = step_reward
278
  else: running_reward = 0.95 * running_reward + 0.05 * step_reward
279
 
280
+
281
  loss = trainer.train_step(experience)
282
 
 
283
  status_dict = {"Rw": f"{running_reward:.2f}"}
284
+
 
285
  if CONFIG['use_progressive_reward'] and hasattr(trainer.math_verifier, 'current_phase'):
286
  status_dict["Ph"] = f"{trainer.math_verifier.current_phase}"
287
 
 
302
  "timestamp": datetime.now().isoformat()
303
  }
304
 
 
305
  if CONFIG['use_progressive_reward'] and hasattr(trainer.math_verifier, 'current_phase'):
306
  metrics_data['reward_phase'] = trainer.math_verifier.current_phase
307
 
 
320
  status_dict["St"] = "Acc"
321
 
322
  progress_bar.set_description(f"{' '.join([f'{k}:{v}' for k,v in status_dict.items()])}")
323
+
 
324
  is_accum_boundary = (len(trainer.experience_buffer) == 0)
325
 
326
  if step > 0 and step % CONFIG['save_interval'] == 0 and IS_MAIN: