Spaces:
Build error
Build error
| import torch | |
| from transformers import ( | |
| AutoModelForCausalLM, | |
| AutoTokenizer, | |
| TrainingArguments, | |
| Trainer, | |
| DataCollatorForSeq2Seq, | |
| ) | |
| from datasets import load_dataset | |
| import os | |
| from huggingface_hub import login, HfApi | |
| # ✅ Configuração Inicial | |
| os.environ["PYTORCH_CUDA_ALLOC_CONF"] = "expandable_segments:True" # Melhora alocação de memória GPUs | |
| # ✅ Autenticação no Hugging Face | |
| HF_API_KEY = os.getenv("HF_API_KEY") | |
| if not HF_API_KEY: | |
| raise ValueError("❌ ERRO: Token Hugging Face não encontrado no ambiente.") | |
| login(HF_API_KEY) | |
| # ✅ Definição de Variáveis | |
| DATASET_NAME = "rwayz/reasoning" # Dataset personalizado | |
| MODEL_NAME = "meta-llama/Llama-3.1-8B-Instruct" # Modelo base | |
| NEW_MODEL_NAME = "APPONTE/reasoning-llama-8b" # Novo modelo treinado | |
| # ✅ Carregamento do Dataset | |
| print(f"🔄 Carregando dataset: {DATASET_NAME}...") | |
| dataset = load_dataset(DATASET_NAME) | |
| print("✅ Dataset carregado com sucesso!") | |
| # ✅ Exibir estrutura do dataset | |
| print("📌 Colunas do dataset:", dataset["train"].column_names) | |
| # ✅ Função para filtrar exemplos inválidos | |
| def filter_invalid_examples(example): | |
| fields = [ | |
| "IdCandidato", "Id", "Tags", "Url", "Url Perfil", "Cadastrado", "Nome", "Sexo", | |
| "Data de Nascimento", "Documento Pessoal", "Cidade", "E-mail", "Telefone", "Etapa atual", | |
| "Status da etapa", "Status na vaga", "Plataforma", "Objetivo profissional", "Tipo formacao", "Nome formacao", "Instituicao formacao", "Inicio formacao", | |
| "Fim formacao", "Conclusao formacao", "Empresa experiencia", "Cargo experiencia", "Inicio experiencia", | |
| "Fim experiencia", "Descricao atividades", "Tempo de experiencias formatado", | |
| "Tempo formatado calculado", "Tipo idioma", "Nivel idioma", "Criado em", "Atualizado em", "Pontuacao Final", "Classificacao Final", "Top", "Aderencia ao Perfil", | |
| "Status Profissional", "porcentagem_escolaridade", "porcentagem_posgraduacao", "porcentagem_idioma", | |
| "porcentagem_experiencias", "porcentagem_experiencia_descricao", "Inconsistencia Experiencia", | |
| "porcentagem_experiencia_desejada", "porcentagem_experiencia_trajetoria", "porcentagem_experiencia_instituicao_ou_setores", | |
| "porcentagem_cargos_e_funcaos", "porcentagem_certificacao", "porcentagem_estabilidade", "porcentagem_cargos_recentes" | |
| ] | |
| return any(bool(str(example.get(field, '')).strip()) for field in fields) | |
| # 🔄 Remover exemplos inválidos | |
| print("🔄 Removendo exemplos inválidos...") | |
| dataset = dataset.filter(filter_invalid_examples) | |
| print(f"✅ Dataset filtrado! {len(dataset['train'])} exemplos restantes.") | |
| # ✅ Função para tratar dados nulos e tokenizar corretamente | |
| def tokenize_function(examples): | |
| inputs = "" | |
| targets = "" | |
| # 🔹 Coletar e tratar todos os campos, convertendo nulos em strings vazias | |
| fields = [ | |
| "IdCandidato", "Id", "Tags", "Url", "Url Perfil", "Cadastrado", "Nome", "Sexo", | |
| "Data de Nascimento", "Documento Pessoal", "Cidade", "E-mail", "Telefone", "Etapa atual", | |
| "Status da etapa", "Status na vaga", "Plataforma", "Objetivo profissional", "Tipo formacao", "Nome formacao", "Instituicao formacao", "Inicio formacao", | |
| "Fim formacao", "Conclusao formacao", "Empresa experiencia", "Cargo experiencia", "Inicio experiencia", | |
| "Fim experiencia", "Descricao atividades", "Tempo de experiencias formatado", | |
| "Tempo formatado calculado", "Tipo idioma", "Nivel idioma", "Criado em", "Atualizado em", "Pontuacao Final", "Classificacao Final", "Top", "Aderencia ao Perfil", | |
| "Status Profissional", "porcentagem_escolaridade", "porcentagem_posgraduacao", "porcentagem_idioma", | |
| "porcentagem_experiencias", "porcentagem_experiencia_descricao", "Inconsistencia Experiencia", | |
| "porcentagem_experiencia_desejada", "porcentagem_experiencia_trajetoria", "porcentagem_experiencia_instituicao_ou_setores", | |
| "porcentagem_cargos_e_funcaos", "porcentagem_certificacao", "porcentagem_estabilidade", "porcentagem_cargos_recentes" | |
| ] | |
| # 🔹 Criar uma string formatada com todas as informações relevantes | |
| inputs = "\n".join([f"{field}: {str(examples.get(field, '') or '').strip()}" for field in fields]) | |
| # 🔹 Definir como alvo a pontuação final, classificação e aderência ao perfil | |
| targets = f"Pontuacao Final: {str(examples.get('Pontuacao Final', '')).strip()} | Classificacao Final: {str(examples.get('Classificacao Final', '')).strip()} | Aderencia ao Perfil: {str(examples.get('Aderencia ao Perfil', '')).strip()}" | |
| # 🔹 Tokenizar input_ids e labels | |
| model_inputs = tokenizer(inputs, padding="max_length", truncation=True, max_length=512) | |
| labels = tokenizer(targets, padding="max_length", truncation=True, max_length=512) | |
| model_inputs["labels"] = labels["input_ids"] | |
| return model_inputs | |
| # 🔹 Aplicar tokenização corretamente e adicionar labels | |
| print("🔄 Tokenizando dataset...") | |
| tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, token=HF_API_KEY) | |
| if tokenizer.pad_token is None: | |
| tokenizer.pad_token = tokenizer.eos_token | |
| model = AutoModelForCausalLM.from_pretrained( | |
| MODEL_NAME, | |
| torch_dtype=torch.bfloat16, | |
| device_map="auto", | |
| token=HF_API_KEY | |
| ) | |
| # ✅ Aplicar a tokenização ao novo dataset | |
| tokenized_datasets = dataset.map(tokenize_function, batched=False, remove_columns=dataset["train"].column_names) | |
| print("✅ Dataset tokenizado!") | |
| # ✅ Criar Data Collator para empacotar os dados | |
| from transformers import DataCollatorForSeq2Seq | |
| data_collator = DataCollatorForSeq2Seq(tokenizer, model=model, padding=True) | |
| # ✅ Ajuste de Hiperparâmetros para LOGS DETALHADOS | |
| training_args = TrainingArguments( | |
| output_dir="./results", | |
| eval_strategy="steps", | |
| eval_steps=1000, # 🔹 Avaliação frequente | |
| save_strategy="steps", | |
| save_steps=2500, # 🔹 Salvar checkpoints | |
| per_device_train_batch_size=2, | |
| per_device_eval_batch_size=2, | |
| gradient_accumulation_steps=4, | |
| num_train_epochs=10, # 🔹 Mais épocas para um treinamento robusto | |
| weight_decay=0.01, | |
| logging_dir="./logs", | |
| logging_strategy="steps", | |
| logging_steps=50, # 🔹 Logs frequentes | |
| save_total_limit=2, | |
| push_to_hub=True, | |
| hub_model_id=NEW_MODEL_NAME, | |
| hub_token=HF_API_KEY, | |
| gradient_checkpointing=True, | |
| bf16=True, | |
| learning_rate=1e-6, # 🔹 Aprendizado mais lento | |
| max_grad_norm=0.2, | |
| warmup_ratio=0.1, | |
| lr_scheduler_type="cosine", | |
| optim="adamw_torch" | |
| ) | |
| # ✅ Configurar Trainer para Fine-Tuning | |
| trainer = Trainer( | |
| model=model, | |
| args=training_args, | |
| train_dataset=tokenized_datasets["train"], | |
| eval_dataset=tokenized_datasets["train"], | |
| data_collator=data_collator, | |
| ) | |
| # ✅ Iniciar Treinamento | |
| print("🚀 Iniciando treinamento do modelo...") | |
| try: | |
| trainer.train() | |
| print("✅ Treinamento concluído!") | |
| except RuntimeError as e: | |
| print(f"❌ ERRO NO TREINAMENTO: {str(e)}") | |
| # ✅ Salvar o Modelo Treinado Localmente | |
| print("💾 Salvando modelo localmente...") | |
| model.save_pretrained("./results") | |
| tokenizer.save_pretrained("./results") | |
| print("✅ Modelo salvo localmente em './results'!") | |
| # ✅ Upload do modelo treinado para Hugging Face | |
| print(f"🔄 Enviando modelo para o Hugging Face: {NEW_MODEL_NAME}...") | |
| api = HfApi() | |
| api.upload_folder( | |
| folder_path="./results", | |
| repo_id=NEW_MODEL_NAME, | |
| repo_type="model", | |
| token=HF_API_KEY | |
| ) | |
| print(f"✅ Modelo salvo no Hugging Face: {NEW_MODEL_NAME}!") | |
| print(f"🔗 Link do modelo: https://huggingface.co/rwayz/{NEW_MODEL_NAME}") |