Script de Entrenamiento Completo
import torch, json, pandas as pd
from datasets import load_dataset
from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig
from peft import LoraConfig, TaskType
from trl import SFTTrainer, SFTConfig
def preprocess(csv_path, out_path):
df = pd.read_csv(csv_path)
system = "Eres el asistente de soporte de TechNest. Responde de forma clara, breve y profesional."
with open(out_path, 'w') as f:
for _, row in df.iterrows():
record = {"messages": [
{"role": "system", "content": system},
{"role": "user", "content": str(row["instruction"])},
{"role": "assistant", "content": str(row["response"])}
]}
f.write(json.dumps(record) + '\n')
model_name = "Qwen/Qwen2.5-7B-Instruct"
bnb_config = BitsAndBytesConfig(load_in_4bit=True, bnb_4bit_quant_type="nf4", bnb_4bit_compute_dtype=torch.bfloat16)
model = AutoModelForCausalLM.from_pretrained(model_name, quantization_config=bnb_config, device_map="auto")
tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.pad_token = tokenizer.eos_token
lora_config = LoraConfig(
task_type=TaskType.CAUSAL_LM, r=16, lora_alpha=32, lora_dropout=0.05,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj"]
)
dataset = load_dataset("json", data_files="data/train.jsonl", split="train")
trainer = SFTTrainer(
model=model,
args=SFTConfig(output_dir="./model-finetune", num_train_epochs=3,
per_device_train_batch_size=2, gradient_accumulation_steps=8,
learning_rate=2e-4, bf16=True, max_seq_length=512,
eval_strategy="epoch", save_strategy="epoch", load_best_model_at_end=True),
train_dataset=dataset, peft_config=lora_config, tokenizer=tokenizer,
)
trainer.train()
trainer.save_model("./model-lora")
print("✓ Fine-tuning completado. Adapter guardado en ./model-lora")