Train using HuggingFace Trainer with a bnb optimizer on CPU.
(args)
| 237 | |
| 238 | |
| 239 | def run_with_trainer(args): |
| 240 | """Train using HuggingFace Trainer with a bnb optimizer on CPU.""" |
| 241 | dtype = get_torch_dtype(args.dtype) |
| 242 | print(f"=== Trainer mode with bnb {args.optimizer} on CPU ({args.dtype}) ===") |
| 243 | print(f"Model: {args.model} | Dataset: {args.dataset}") |
| 244 | print(f"Steps: {args.steps} | LR: {args.lr} | Batch: {args.batch_size} | MaxLen: {args.max_length}") |
| 245 | print() |
| 246 | |
| 247 | tokenizer = AutoTokenizer.from_pretrained(args.model) |
| 248 | if tokenizer.pad_token is None: |
| 249 | tokenizer.pad_token = tokenizer.eos_token |
| 250 | |
| 251 | model = AutoModelForCausalLM.from_pretrained(args.model, dtype=dtype) |
| 252 | |
| 253 | ds = prepare_data(tokenizer, args.dataset, args.max_length) |
| 254 | |
| 255 | training_args = TrainingArguments( |
| 256 | output_dir="./cpu_trainer_output", |
| 257 | per_device_train_batch_size=args.batch_size, |
| 258 | max_steps=args.steps, |
| 259 | logging_steps=args.log_interval, |
| 260 | learning_rate=args.lr, |
| 261 | save_strategy="steps", |
| 262 | save_steps=args.steps, |
| 263 | save_total_limit=1, |
| 264 | report_to="none", |
| 265 | bf16=(args.dtype == "bf16"), |
| 266 | use_cpu=True, |
| 267 | dataloader_pin_memory=False, |
| 268 | ) |
| 269 | |
| 270 | optimizer = create_optimizer(model, args.optimizer, args.lr) |
| 271 | scheduler = torch.optim.lr_scheduler.ConstantLR(optimizer, factor=1.0) |
| 272 | |
| 273 | trainer = Trainer( |
| 274 | model=model, |
| 275 | args=training_args, |
| 276 | train_dataset=ds, |
| 277 | data_collator=collate_fn, |
| 278 | optimizers=(optimizer, scheduler), |
| 279 | ) |
| 280 | |
| 281 | train_result = trainer.train() |
| 282 | metrics = train_result.metrics |
| 283 | print("\n--- Trainer Results ---") |
| 284 | print(f"Training loss: {metrics['train_loss']:.4f}") |
| 285 | print(f"Training runtime: {metrics['train_runtime']:.1f}s") |
| 286 | print(f"Steps/sec: {metrics['train_steps_per_second']:.1f}") |
| 287 | print(f"Optimizer: bnb.optim.{args.optimizer} | Dtype: {args.dtype}") |
| 288 | |
| 289 | save_dir = "./cpu_trainer_output/final" |
| 290 | print(f"\nSaving model and tokenizer to {save_dir} ...") |
| 291 | trainer.save_model(save_dir) |
| 292 | tokenizer.save_pretrained(save_dir) |
| 293 | print("Save complete.") |
| 294 | |
| 295 | # Verify saved model can be loaded back |
| 296 | print("Verifying saved model loads correctly ...") |
no test coverage detected