Instructions to use Grupo-de-Estudos-GPRSW/meditron-7b-finetuned-MedQuAD with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use Grupo-de-Estudos-GPRSW/meditron-7b-finetuned-MedQuAD with PEFT:
from peft import PeftModel from transformers import AutoModelForCausalLM base_model = AutoModelForCausalLM.from_pretrained("epfl-llm/meditron-7B") model = PeftModel.from_pretrained(base_model, "Grupo-de-Estudos-GPRSW/meditron-7b-finetuned-MedQuAD") - Notebooks
- Google Colab
- Kaggle
meditron-7b-finetuned-MedQuAD
Adaptador LoRA que especializa o epfl-llm/meditron-7B em perguntas e respostas médicas no
estilo do MedQuAD — o conjunto de pares pergunta/resposta extraídos de sites do NIH
(CancerGov, GARD, GHR, MedlinePlus, NIDDK, NINDS, NIHSeniorHealth, NHLBI e CDC).
O repositório contém apenas os pesos do adaptador (~17 MB) e o tokenizer, não um modelo mesclado: o modelo base (~13 GB) é baixado à parte e o adaptador é aplicado sobre ele.
⚠️ Este modelo é um trabalho acadêmico e não é um dispositivo médico. Ele não deve ser usado para diagnóstico, prescrição ou qualquer decisão clínica. Veja Limitações: na avaliação, a única pergunta clínica fora do dataset que exigia raciocínio produziu uma diretriz inventada, defendida por 256 tokens.
Detalhes do modelo
| Modelo base | epfl-llm/meditron-7B (6,74 B parâmetros, arquitetura Llama) |
| Tipo de ajuste | QLoRA (LoRA sobre modelo base quantizado em 4-bit) |
| Parâmetros treináveis | 8.388.608 (0,124% do modelo) — 256 tensores: 32 camadas × 4 projeções × matrizes A/B |
| Tamanho do artefato | ~17 MB (adapter_model.safetensors) |
| Idioma | Inglês |
| Tarefa | Geração de texto (resposta a perguntas médicas) |
| Licença | Herdada do modelo base (Llama 2 Community License, via Meditron) |
| Desenvolvido por | Grupo de Estudos GPRSW — Tech Challenge Fase 3, Pós-Tech |
Uso pretendido
Para o que serve. Responder, em inglês, perguntas de consumidor sobre doenças, sintomas, tratamentos, exames, prevenção e herança genética, reproduzindo o formato editorial do MedQuAD (parágrafo de abertura seguido de lista com marcadores). Serve como componente de estudo em pipelines de RAG e como demonstração de fine tuning eficiente em GPU de consumo.
Para o que não serve. Diagnóstico, prescrição, triagem, aconselhamento a pacientes, apoio à decisão clínica, uso em outro idioma que não o inglês, ou qualquer contexto em que uma resposta errada tenha custo real. O modelo não cita fontes e não sabe dizer quando não sabe.
Como usar
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
from peft import PeftModel
BASE = "epfl-llm/meditron-7B"
ADAPTER = "Grupo-de-Estudos-GPRSW/meditron-7b-finetuned-MedQuAD"
# Mesma quantização usada no treino: ~4 GB de VRAM em vez de ~13,5 GB em fp16.
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.float16,
bnb_4bit_use_double_quant=True,
)
tokenizer = AutoTokenizer.from_pretrained(ADAPTER)
base_model = AutoModelForCausalLM.from_pretrained(
BASE, device_map="cuda", quantization_config=bnb_config
)
model = PeftModel.from_pretrained(base_model, ADAPTER)
prompt = """###System:
You are a helpful, respectful, and honest assistant. Always answer as helpfully as possible, while being safe. Your answers should not include any harmful, unethical, racist, sexist, toxic, dangerous, or illegal content. Please ensure that your responses are socially unbiased and positive in nature.
If a question does not make any sense, or is not factually coherent, explain why instead of answering something not correct. If you don't know the answer to a question, don't share false information.
### User:
What are the symptoms of Marfan syndrome ?
### Assistant:
"""
inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
output = model.generate(
**inputs,
max_new_tokens=256,
pad_token_id=tokenizer.eos_token_id,
repetition_penalty=1.15, # recomendado: ver Limitações
)
texto = tokenizer.decode(output[0], skip_special_tokens=True)
resposta = texto.split("### Assistant:")[1]
# O modelo às vezes não para no fim da resposta e abre turnos novos por conta própria:
# corte no primeiro marcador seguinte (ver Limitações).
for marcador in ("### User:", "###System:", "### Assistant:"):
resposta = resposta.split(marcador)[0]
print(resposta.strip())
Com versões recentes do transformers (integração PEFT), AutoModelForCausalLM.from_pretrained(ADAPTER)
também resolve o base pelo base_model_name_or_path do adapter_config.json e dispensa o
PeftModel explícito.
Template de prompt
O ajuste usou o template do model card do Meditron, com o eos_token ao fim da resposta.
Usar o mesmo template na inferência é obrigatório — foi o marcador ### Assistant: que o
modelo aprendeu, e é nele que a saída deve ser cortada:
###System:
{instrução de segurança padrão do Meditron}
### User:
{pergunta}
### Assistant:
{resposta}<eos>
Dados de treino
MedQuAD (Ben Abacha & Demner-Fushman, 2019), clonado do repositório original e parseado dos XMLs.
| Pares pergunta/resposta encontrados | 47.441 |
| Pares usados no treino | 16.407 |
| Pares descartados | 31.034 (resposta vazia) |
Os descartes não são um defeito do parse: parte do MedQuAD teve as respostas removidas por questões de licenciamento, e só ficam os pares em que pergunta e resposta existem e não são vazias. Não houve nenhuma separação treino/validação/teste — todos os 16.407 pares foram usados no treino (ver Avaliação).
Procedimento de treino
Modelo base carregado em 4-bit (nf4, compute em float16, double quant), preparado com
prepare_model_for_kbit_training e treinado com SFTTrainer (TRL).
LoRA
| Parâmetro | Valor |
|---|---|
r |
8 |
lora_alpha |
32 |
lora_dropout |
0,05 |
target_modules |
q_proj, k_proj, v_proj, o_proj |
bias |
none |
task_type |
CAUSAL_LM |
Treino
| Parâmetro | Valor |
|---|---|
| Épocas | 3 |
| Batch por dispositivo × acumulação | 4 × 4 (batch efetivo 16) |
| Passos | ≈ 3.076 (16.407 × 3 ÷ 16) |
| Learning rate | 2e-4, scheduler linear, 5 passos de warmup |
| Otimizador | adamw_8bit |
max_length / packing |
512 / False |
| Seed | 74 |
| Hardware | 1× NVIDIA RTX 3060 12 GB |
Avaliação
Bateria de 13 itens: 10 perguntas amostradas do MedQuAD (uma por fonte, com resposta de
referência) e 3 sondas clínicas escritas fora do dataset. Geração determinística
(do_sample=False), max_new_tokens=256, seed 74, pesos em fp16 numa RTX 3060 de 12,9 GB.
| Métrica (média) | Valor | Mín | Máx |
|---|---|---|---|
| ROUGE-L | 0,261 | 0,088 | 0,435 |
| Token F1 | 0,354 | 0,151 | 0,497 |
| Precisão de tokens | 0,636 | 0,261 | 1,000 |
| Recall de tokens | 0,282 | 0,089 | 0,486 |
| Repetição de trigramas | 0,121 | 0,000 | 0,541 |
| Tokens gerados | 170,9 | 34 | 256 |
| Comportamento | Resultado |
|---|---|
| Parou por EOS (não bateu no teto de 256) | 7/13 (53,8%) |
| Respostas vazias | 0/13 |
| Respostas com artefato de fonte ("GARD", "visit the…") | 0/13 |
Como ler esses números. Precisão 0,64 contra recall 0,28: quase dois terços das palavras que
o modelo escreve aparecem na referência, mas ele cobre pouco mais de um quarto do conteúdo dela
— respostas mais curtas, no vocabulário e no formato certos. O ajuste também ensinou o modelo a
parar (o eos_token do template) e limpou os artefatos editoriais das fontes originais.
As métricas não medem generalização. Como todo o MedQuAD entrou no treino, as 10 perguntas avaliadas são dados vistos: os valores acima medem aderência/memorização do formato de treino, não capacidade em perguntas novas. Trate-os como diagnóstico de ajuste, não como benchmark.
Custo de inferência
Medido em fp16, numa RTX 3060 de 12,9 GB:
| Medida | Valor |
|---|---|
| Pico de VRAM | 13,75 GB |
| Carga do modelo | 747 s |
| Tokens por segundo | 1,5 |
| Segundos por resposta (média) | 114,9 |
Esses números são de uma configuração mal dimensionada, e valem como aviso. Em fp16 os pesos
ocupam ~13,5 GB: numa placa de 12,9 GB o modelo não falha — transborda para a memória
compartilhada e fica lento a ponto de inviabilizar uso interativo. Numa placa de 6 GB, o mesmo
transbordo termina em CUDA out of memory na primeira geração, depois de o carregamento
aparentar sucesso.
Use 4-bit (nf4, a mesma configuração do treino, ~4 GB) a menos que você tenha 16 GB de VRAM
ou mais.
Limitações e riscos
- Erro factual em perguntas fora do dataset. Perguntado sobre o tratamento de um paciente com diabetes tipo 2 já em uso de metformina e lisinopril, o modelo respondeu que "the ADA recommends that people with type 2 diabetes take metformin and lisinopril together" e passou os 256 tokens seguintes enumerando classes de antidiabéticos que a combinação supostamente supera. O lisinopril é anti-hipertensivo, não antidiabético, e a diretriz não existe. O modelo produz texto plausível e confiante mesmo quando erra.
- Conduta categórica sem os dados. A outra sonda clínica ("um paciente com doença coronariana em uso de aspirina e atorvastatina, com teste de esforço pendente — devo prescrever algo novo?") foi respondida com "No. […] you should not prescribe any additional medications", sem considerar o exame que a própria pergunta declara pendente.
- Respostas vazias de conteúdo. A terceira sonda foi respondida em 34 tokens que apenas reformulam a pergunta ("é importante fazer acompanhamento para confirmar que a pneumonia foi tratada").
- Não para no fim da resposta. Em 6 dos 13 itens o modelo consumiu todo o teto de tokens, e
em vários deles continuou gerando depois de ter terminado a resposta — abrindo novos turnos
### User:/### Assistant:por conta própria. Num item, dos 256 tokens gerados sobraram 46 palavras depois do corte no primeiro marcador. Dentro de um pipeline, esses turnos chegaram a contradizer o que o modelo acabara de dizer ("you should prescribe aspirin", seguido de "No. You should not prescribe a new medication") e a derivar para condições que o paciente não tinha. Corte a saída no primeiro marcador seguinte ou useStoppingCriteria(ver Como usar). - Degeneração por repetição. Em 1 dos 13 itens a resposta repetiu a mesma construção até
esgotar o teto de tokens (0,54 de repetição de trigramas). Use
repetition_penalty(~1,15) ouno_repeat_ngram_size. - Sem separação treino/teste, o que impede afirmar qualquer coisa sobre generalização.
- Herda os vieses e o corte de conhecimento do
epfl-llm/meditron-7Be do MedQuAD: conteúdo do NIH, em inglês, centrado no contexto de saúde dos Estados Unidos, sem atualização posterior à coleta do dataset. - Não cita fontes e não distingue o que sabe do que não sabe; as respostas cobrem parcialmente o assunto perguntado.
- Só faz sentido em inglês — não houve dado de treino em português.
Reprodução
O código do ajuste está na pasta finetuning/ do projeto: config.py (hiperparâmetros),
data_loading.py (clone e parse do MedQuAD), foundation_model.py (quantização 4-bit),
dataset_formatting.py (template) e training.py (LoRA + SFTTrainer), todos derivados do
notebook medical_chatbot_finetuning.ipynb.
Os números de avaliação deste card vêm da suíte eval/ do mesmo projeto
(python run_eval.py --quantization none, resultados brutos em eval/results/model.json).
Dependências principais: transformers, peft, trl, bitsandbytes, accelerate, datasets.
Requer GPU NVIDIA com CUDA — bitsandbytes em 4-bit não roda em CPU.
Créditos e citação
Modelo base: Meditron (EPFL LLM Team).
Dataset:
@ARTICLE{BenAbacha-BMC-2019,
author = {Asma Ben Abacha and Dina Demner{-}Fushman},
title = {A Question-Entailment Approach to Question Answering},
journal = {BMC Bioinform.},
volume = {20},
number = {1},
pages = {511:1--511:23},
year = {2019}
}
Adaptador: Grupo de Estudos GPRSW, Tech Challenge Fase 3 (Pós-Tech).
- Downloads last month
- 112