qwen3.5_0.8b_finetune.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. """
  2. Qwen3.5 0.8B 模型微调示例
  3. 这个脚本演示了如何使用 FineTuneX 框架微调 Qwen3.5 模型。
  4. 注意:Qwen3.5-0.8B 尚未正式发布,这里使用 Qwen3.5-0.5B 作为示例。
  5. 使用方法:
  6. python examples/qwen3.5_0.8b_finetune.py
  7. """
  8. import os
  9. import sys
  10. # 添加项目根目录到 Python 路径
  11. sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
  12. from finetunex.models import QwenConfig, load_qwen_model
  13. from finetunex.data import load_dataset, format_dataset, InstructionDataset
  14. from finetunex.trainer import FineTuneTrainer
  15. from finetunex.utils import setup_environment, get_gpu_info, setup_logger
  16. def main():
  17. # 设置环境和日志
  18. setup_environment(seed=42)
  19. logger = setup_logger("Qwen3.5_FineTuning")
  20. logger.info("=" * 60)
  21. logger.info("Qwen3.5 0.8B 微调示例")
  22. logger.info("=" * 60)
  23. # 显示 GPU 信息
  24. gpu_info = get_gpu_info()
  25. if gpu_info["available"]:
  26. logger.info(f"GPU 可用:{gpu_info['device_count']} 个设备")
  27. for i, dev in enumerate(gpu_info["devices"]):
  28. logger.info(f" GPU {i}: {dev['name']} ({dev['max_memory']:.2f} GB)")
  29. else:
  30. logger.warning("GPU 不可用,将使用 CPU 训练(不推荐)")
  31. # 1. 配置模型
  32. # 注意:Qwen3.5-0.8B 尚未发布,使用 Qwen3.5-0.5B 替代
  33. # 如果 Qwen3.5-0.8B 发布后,可以改为 "Qwen/Qwen3.5-0.8B"
  34. config = QwenConfig(
  35. model_name="Qwen/Qwen3.5-0.5B", # 或 "Qwen/Qwen3.5-0.8B" 当可用时
  36. lora_r=16,
  37. lora_alpha=32,
  38. lora_dropout=0.05,
  39. target_modules=[
  40. "q_proj",
  41. "k_proj",
  42. "v_proj",
  43. "o_proj",
  44. "gate_proj",
  45. "up_proj",
  46. "down_proj",
  47. ],
  48. per_device_train_batch_size=1,
  49. gradient_accumulation_steps=4,
  50. learning_rate=2e-4,
  51. num_train_epochs=3,
  52. max_seq_length=512,
  53. output_dir="./outputs/qwen3.5-0.5b-finetuned",
  54. use_4bit=False, # 华为升腾 NPU 不支持 4bit 量化
  55. )
  56. logger.info(f"模型配置:{config.model_name}")
  57. logger.info(f"LoRA 配置:r={config.lora_r}, alpha={config.lora_alpha}")
  58. logger.info(f"训练配置:epochs={config.num_train_epochs}, lr={config.learning_rate}")
  59. # 2. 加载数据集
  60. dataset_path = os.path.join(os.path.dirname(__file__), "..", "data", "sample_dataset.json")
  61. dataset = load_dataset(dataset_path, format="json")
  62. # 格式化数据集
  63. formatted_dataset = format_dataset(
  64. dataset,
  65. instruction_column="instruction",
  66. input_column="input",
  67. output_column="output",
  68. )
  69. logger.info(f"数据集大小:{len(formatted_dataset)} 样本")
  70. # 3. 加载模型和 tokenizer
  71. model, tokenizer, peft_config = load_qwen_model(config)
  72. # 4. 创建训练数据集
  73. train_dataset = InstructionDataset(
  74. formatted_dataset,
  75. tokenizer,
  76. max_length=config.max_seq_length,
  77. )
  78. # 5. 创建训练器
  79. trainer = FineTuneTrainer(
  80. model=model,
  81. tokenizer=tokenizer,
  82. config=config,
  83. train_dataset=train_dataset,
  84. )
  85. # 6. 设置训练参数
  86. trainer.setup_training(
  87. output_dir=config.output_dir,
  88. num_train_epochs=config.num_train_epochs,
  89. per_device_train_batch_size=config.per_device_train_batch_size,
  90. gradient_accumulation_steps=config.gradient_accumulation_steps,
  91. learning_rate=config.learning_rate,
  92. warmup_ratio=0.03,
  93. weight_decay=0.01,
  94. logging_steps=10,
  95. save_steps=50,
  96. bf16=True,
  97. fp16=False,
  98. )
  99. # 7. 开始训练
  100. logger.info("开始训练...")
  101. trainer.train()
  102. # 8. 保存模型
  103. trainer.save_model()
  104. logger.info("=" * 60)
  105. logger.info("训练完成!")
  106. logger.info(f"模型已保存到:{config.output_dir}")
  107. logger.info("=" * 60)
  108. # 9. 测试推理(可选)
  109. logger.info("\n测试推理...")
  110. test_prompt = "请解释什么是人工智能"
  111. inputs = tokenizer(test_prompt, return_tensors="pt")
  112. if torch.cuda.is_available():
  113. inputs = inputs.to("cuda")
  114. elif hasattr(torch, 'npu') and torch.npu.is_available():
  115. inputs = inputs.to("npu:0")
  116. with torch.no_grad():
  117. outputs = model.generate(
  118. **inputs,
  119. max_new_tokens=100,
  120. temperature=0.7,
  121. do_sample=True,
  122. )
  123. response = tokenizer.decode(outputs[0], skip_special_tokens=True)
  124. logger.info(f"输入:{test_prompt}")
  125. logger.info(f"输出:{response}")
  126. if __name__ == "__main__":
  127. import torch
  128. main()