Microajustando o DeepSeek R1 para Aplicações de Diagnóstico Médico

Neste guia técnico, vamos microajustar o modelo DeepSeek-R1-Distill-Llama-8B para tarefas de raciocínio clínico, utilizando um conjunto de dados de cadeia de pensamento médico do Hugging Face. O DeepSeek-R1 é um modelo de raciocínio de código aberto que oferece desempenho comparável a modelos proprietários, e sua versão destilada mantém capacidades avançadas em um pacote mais eficiente.

Conceitos Fundamentais do DeepSeek R1

O DeepSeek-R1-Zero foi treinado exclusivamente com aprendizado por reforço em larga escala, permitindo que o modelo desenvolvesse raciocínio autônomo de cadeia de pensamento. No entanto, apresentava desafios como repetição de etapas e legibilidade reduzida. A versão DeepSeek-R1 aprimorada introduz dados de inicialização a frio antes do treinamento por reforço, melhorando a coerência e a eficiência em tarefas de lógica e diagnóstico.

Os modelos destilados do DeepSeek, com parâmetros variando de 1.5B a 70B, retêm fortes capacidades de raciocínio. Por exemplo, o DeepSeek-R1-Distill-Qwen-32B supera modelos comparáveis em benchmarks específicos, demonstrando a eficácia da destilação.

Passos para Microajustamento

1. Configuração do Ambiente

Utilizaremos uma plataforma com GPU, como Kaggle, e o framework Unsloth para microajustamento eficiente. Comece instalando as dependências necessárias:


!pip install unsloth
!pip install --upgrade --no-cache-dir git+https://github.com/unslothai/unsloth.git

Autentique-se no Hugging Face Hub e no Weights & Biases para gerenciar modelos e experimentos:


from huggingface_hub import login
from kaggle_secrets import UserSecretsClient
segredos = UserSecretsClient()
token_hf = segredos.get_secret("HUGGINGFACE_TOKEN")
login(token_hf)

import wandb
token_wb = segredos.get_secret("wandb")
wandb.login(key=token_wb)
execucao = wandb.init(project='Microajustamento-DeepSeek-R1-Medico', job_type="training")

2. Carregamento do Modelo e Tokenizer

Carregue a versão Unsloth do modelo com quantização de 4 bits para otimizar memória:


from unsloth import FastLanguageModel
comprimento_max_seq = 2048
tipo_dado = None
carregar_em_4bit = True

modelo, tokenizador = FastLanguageModel.from_pretrained(
    model_name="unsloth/DeepSeek-R1-Distill-Llama-8B",
    max_seq_length=comprimento_max_seq,
    dtype=tipo_dado,
    load_in_4bit=carregar_em_4bit,
    token=token_hf,
)

3. Inferência Pré-microajustamento

Defina um modelo de prompt para guiar o raciocínio do modelo. Este prompt instrui o modelo a pensar passo a passo antes de responder:


modelo_prompt = """
Abaixo está uma instrução que descreve uma tarefa, acompanhada de uma entrada com contexto adicional.
Escreva uma resposta que complete adequadamente a solicitação.
Antes de responder, considere cuidadosamente a questão e crie uma cadeia de pensamentos passo a passo para garantir uma resposta lógica e precisa.

### Instrução:
Você é um especialista médico com conhecimento avançado em raciocínio clínico, diagnósticos e planejamento de tratamento.
Por favor, responda à seguinte questão médica.

### Questão:
{}

### Resposta:
{}
"""

Execute uma inferência de teste com uma questão médica para verificar o comportamento inicial do modelo:


questao = "Uma mulher de 61 anos com histórico de perda urinária involuntária durante atividades como tosse ou espirro, mas sem vazamentos noturnos, passa por exame ginecológico e teste de Q-tip. Com base nesses achados, o que a cistometria provavelmente revelaria sobre seu volume residual e contrações do detrusor?"
FastLanguageModel.for_inference(modelo)
entradas = tokenizador([modelo_prompt.format(questao, "")], return_tensors="pt").to("cuda")
saidas = modelo.generate(
    input_ids=entradas.input_ids,
    attention_mask=entradas.attention_mask,
    max_new_tokens=1200,
    use_cache=True,
)
resposta = tokenizador.batch_decode(saidas)
print(resposta[0].split("### Resposta:")[1])

O modelo gera uma cadeia de raciocínio, mas a resposta pode ser verbosa. O microajustamento visará refinar a precisão e a concisão.

4. Preparação do Conjunto de Dados

Adapte o modelo de prompt para incluir uma seção de cadeia de pensamento complexa durante o treinamento:


modelo_prompt_treino = """
Abaixo está uma instrução que descreve uma tarefa, acompanhada de uma entrada com contexto adicional.
Escreva uma resposta que complete adequadamente a solicitação.
Antes de responder, considere cuidadosamente a questão e crie uma cadeia de pensamentos passo a passo para garantir uma resposta lógica e precisa.

### Instrução:
Você é um especialista médico com conhecimento avançado em raciocínio clínico, diagnósticos e planejamento de tratamento.
Por favor, responda à seguinte questão médica.

### Questão:
{}

### Resposta:
{}

{}
"""

Crie uma função para formatar o conjunto de dados, preenchendo os placeholders com questões, cadeias de pensamento e respostas:


TOKEN_FIM = tokenizador.eos_token

def formatar_exemplos(exemplos):
    entradas = exemplos["Question"]
    raciocinios = exemplos["Complex_CoT"]
    saidas = exemplos["Response"]
    textos = []
    for entrada, raciocinio, saida in zip(entradas, raciocinios, saidas):
        texto = modelo_prompt_treino.format(entrada, raciocinio, saida) + TOKEN_FIM
        textos.append(texto)
    return {"text": textos}

Carregue um subconjunto do conjunto de dados médico do Hugging Face e aplique a formatação:


from datasets import load_dataset
conjunto_dados = load_dataset("FreedomIntelligence/medical-o1-reasoning-SFT", split="train[:500]")
conjunto_dados = conjunto_dados.map(formatar_exemplos, batched=True)

5. Configuração do Modelo para Treinamento

Aplicação de LoRA (Adaptadores de Baixa Classe) para microajustamento eficiente:


modelo = FastLanguageModel.get_peft_model(
    modelo,
    r=16,
    target_modules=["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"],
    lora_alpha=16,
    lora_dropout=0,
    bias="none",
    use_gradient_checkpointing="unsloth",
    random_state=3407,
)

Configure os argumentos de treinamento e o treinador:


from trl import SFTTrainer
from transformers import TrainingArguments
from unsloth import is_bfloat16_supported

treinador = SFTTrainer(
    model=modelo,
    tokenizer=tokenizador,
    train_dataset=conjunto_dados,
    dataset_text_field="text",
    max_seq_length=comprimento_max_seq,
    args=TrainingArguments(
        per_device_train_batch_size=2,
        gradient_accumulation_steps=4,
        warmup_steps=5,
        max_steps=60,
        learning_rate=2e-4,
        fp16=not is_bfloat16_supported(),
        bf16=is_bfloat16_supported(),
        logging_steps=10,
        optim="adamw_8bit",
        weight_decay=0.01,
        lr_scheduler_type="linear",
        seed=3407,
        output_dir="resultados",
    ),
)

6. Execução do Treinamento

Inicie o processo de treinamento e monitore a perda através do Weights & Biases:


estatisticas_treinamento = treinador.train()

7. Inferência Pós-microajustamento

Teste o modelo microajustado com a mesma questão médica para avaliar melhorias:


FastLanguageModel.for_inference(modelo)
entradas = tokenizador([modelo_prompt.format(questao, "")], return_tensors="pt").to("cuda")
saidas = modelo.generate(
    input_ids=entradas.input_ids,
    attention_mask=entradas.attention_mask,
    max_new_tokens=1200,
    use_cache=True,
)
resposta_final = tokenizador.batch_decode(saidas)
print(resposta_final[0].split("### Resposta:")[1])

A resposta microajustada deve ser mais concisa e precisa, com uma cadeia de raciocínio simplificada.

8. Persistência do Modelo

Salve o modelo, tokenizer e adaptadores localmente:


nome_modelo_local = "DeepSeek-R1-Medico-OT"
modelo.save_pretrained(nome_modelo_local)
tokenizador.save_pretrained(nome_modelo_local)
modelo.save_pretrained_merged(nome_modelo_local, tokenizador, save_method="merged_16bit")

Faça o upload para o Hugging Face Hub para compartilhamento:


nome_modelo_online = "seu_usuario/DeepSeek-R1-Medico-OT"
modelo.push_to_hub(nome_modelo_online)
tokenizador.push_to_hub(nome_modelo_online)
modelo.push_to_hub_merged(nome_modelo_online, tokenizador, save_method="merged_16bit")

Tags: deepseek LLM Microajustamento Inteligência Artificial Médica Hugging Face

Publicado em 7-2 21:39