Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/NicolasHoyosDevss/MaternaQA-es/llms.txt

Use this file to discover all available pages before exploring further.

Two inference scripts are provided: inference_base.py for baseline predictions with unmodified models, and inference_qlora.py for models with trained QLoRA adapters. Both scripts operate on the held-out test split (328 pairs), write one prediction per line to a JSONL file, and support resumable execution — if the run is interrupted, re-running the same command picks up from where it left off. Output files from both scripts can be passed directly into evaluate_model_predictions.py for Ragas-based scoring.

Base Model Inference

inference_base.py loads a base model without any adapter and generates predictions over the test split. Use this to establish a pre-fine-tuning baseline for comparison against QLoRA-adapted models.

CLI Flags

FlagTypeDefaultDescription
--model-namestr(required)Hugging Face model ID or local path
--model-classauto|causal-lm|image-text-to-textautoModel loader class; auto selects ImageTextToText for Gemma 4 / MedGemma
--dataset-rootPathdatasets/obstetrics/qa/publicationRoot directory of the dataset variants
--dataset-variantsft_closed_book|sft_groundedsft_groundedWhich test split to run inference on
--output-prefixPath(required)Path prefix; output is written to <prefix>_predictions.jsonl
--max-new-tokensint512Maximum tokens to generate per answer
--temperaturefloat0.7Sampling temperature (only used when --do-sample is set)
--top-pfloat0.9Nucleus sampling threshold (only used when --do-sample is set)
--do-sampleflagFalseEnable stochastic sampling; default is greedy decoding for reproducibility
--limitintNoneEvaluate only the first N examples (for smoke tests)
--trust-remote-codeflagFalsePass trust_remote_code=True to the model loader
--attn-implementationstrNoneOptional attention backend override
--load-in-4bitboolTrueLoad the base model in 4-bit NF4 for comparable VRAM usage
--resume / --no-resumeboolTrueResume from existing output file; use --no-resume to overwrite

Usage

python scripts/inference_base.py \
  --model-name google/gemma-4-E2B-it \
  --output-prefix outputs/gemma4-base/test
The script loads the base model in 4-bit NF4 quantization, applies the tokenizer’s chat template to construct prompts from the test split, and writes predictions incrementally to outputs/gemma4-base/test_predictions.jsonl as it generates each response.

QLoRA Adapter Inference

inference_qlora.py loads a base model in 4-bit quantization and mounts a trained PEFT adapter on top before running inference. The base model is identified automatically from adapter_config.json inside the adapter directory — you do not need to specify it separately.

CLI Flags

FlagTypeDefaultDescription
--adapter-dirPath(required)Directory containing adapter_model.safetensors and adapter_config.json
--dataset-variantsft_closed_book|sft_groundedsft_groundedWhich test split to run inference on
--output-prefixPath(required)Path prefix; output is written to <prefix>_predictions.jsonl
--max-new-tokensint512Maximum tokens to generate per answer
--temperaturefloat0.7Sampling temperature (only used when --do-sample is set)
--top-pfloat0.9Nucleus sampling threshold (only used when --do-sample is set)
--do-sampleflagFalseEnable stochastic sampling; default is greedy decoding for reproducibility
--limitintNoneEvaluate only the first N examples (for smoke tests)
--trust-remote-codeflagFalsePass trust_remote_code=True to the model loader
--attn-implementationstrNoneOptional attention backend override
--resume / --no-resumeboolTrueResume from existing output file; use --no-resume to overwrite

Usage

python scripts/inference_qlora.py \
  --adapter-dir outputs/gemma4-grounded \
  --output-prefix outputs/gemma4-grounded/test
The script reads adapter_config.json to determine the base model, loads it in 4-bit NF4 quantization, mounts the adapter via PeftModel.from_pretrained, sets the model to eval mode, and writes predictions incrementally to the output JSONL file.

Output Format

Both scripts write one JSON object per line to <output-prefix>_predictions.jsonl. Each record contains the following fields:
{
  "id": "obs-train-001",
  "model_role": "qlora",
  "model_name": "google/gemma-4-E2B-it",
  "adapter_dir": "outputs/gemma4-grounded",
  "dataset_variant": "sft_grounded",
  "question": "¿Cuáles son los factores de riesgo para preeclampsia?",
  "generated_answer": "Los factores de riesgo incluyen...",
  "reference_answer": "Entre los factores de riesgo se encuentran...",
  "source_context": "Contexto fuente del fragmento clínico...",
  "prompt_text": "<bos><start_of_turn>user\n...<end_of_turn>\n<start_of_turn>model\n",
  "reference_messages": [...],
  "metadata": {
    "qa_id": "obs-train-001",
    "source_pdf": "guia-preeclampsia.pdf",
    "tipo": "razonamiento",
    "dificultad": "media",
    "chunk_id": "chunk-042",
    "topics": ["preeclampsia", "prenatal_care"]
  }
}
For base model runs, model_role is "base" and adapter_dir is null. For QLoRA runs, model_role is "qlora" and adapter_dir points to the loaded adapter directory.

Evaluate Predictions

Pass any _predictions.jsonl file into evaluate_model_predictions.py to score it with Ragas metrics. The evaluator requires OPENAI_API_KEY in the environment.

CLI Flags

FlagTypeDefaultDescription
--inputPath(required)JSONL predictions file from inference_base.py or inference_qlora.py
--outputPath<input_stem>_eval.jsonSummary JSON report path
--output-jsonlPath<output>.jsonlPer-prediction detail JSONL path
--limitintNoneEvaluate only the first N rows
--timeout-secondsint180Per-prediction timeout for Ragas LLM calls
--llm-modelstrgpt-5.4-miniOpenAI model used as the Ragas LLM judge
--embedding-modelstrtext-embedding-3-smallOpenAI embeddings model for semantic metrics
--max-completion-tokensint2048Output token limit for the LLM judge
--metricslistfaithfulness answer_relevancy answer_correctness semantic_similarityWhich Ragas metrics to compute
--resume / --no-resumeboolTrueResume from --output-jsonl if it exists
--estimate-onlyflagFalseEstimate token volume without calling OpenAI
python scripts/evaluate_model_predictions.py \
  --input outputs/gemma4-grounded/test_predictions.jsonl \
  --output outputs/gemma4-grounded/test_eval.json

Comparing Models

Pre-computed prediction files are available in the repository under the following directories, covering both base and fine-tuned variants:
  • outputs/gemma4-base/ — Gemma 4 E2B without any adapter
  • outputs/gemma4-grounded/ — Gemma 4 E2B with sft_grounded QLoRA adapter
  • outputs/medgemma-base/ — MedGemma 1.5 4B IT without any adapter
  • outputs/medgemma-grounded/ — MedGemma 1.5 4B IT with sft_grounded QLoRA adapter
Use convert_eval_to_csv.py to export all evaluated models to CSV for paper analysis. The script scans the outputs/ directory for test_eval.jsonl files and produces three CSV files:
  • master_eval.csv — one row per (model, qa_id) with all metrics and metadata
  • model_summary.csv — one row per model with aggregate scores
  • wide_comparison.csv — one row per qa_id with side-by-side answers and scores per model
python scripts/convert_eval_to_csv.py \
  --outputs-dir outputs/ \
  --out-dir csv_outputs/
FlagTypeDefaultDescription
--outputs-dirstroutputsDirectory containing model subdirectories with test_eval.jsonl files
--out-dirstrcsv_outputsDirectory where the three CSV files are written

Quick Evaluation Workflow

1

Run Inference

Generate predictions on the held-out test split. Use inference_base.py to create a pre-training baseline, or inference_qlora.py to score a trained adapter.
python scripts/inference_qlora.py \
  --adapter-dir outputs/gemma4-grounded \
  --output-prefix outputs/gemma4-grounded/test
2

Evaluate with Ragas

Score the predictions against the reference answers and source contexts using evaluate_model_predictions.py. The script writes a per-prediction detail JSONL and a JSON summary report.
python scripts/evaluate_model_predictions.py \
  --input outputs/gemma4-grounded/test_predictions.jsonl \
  --output outputs/gemma4-grounded/test_eval.json
3

Export to CSV

Convert all evaluated model outputs to flat CSV files for cross-model comparison and academic analysis.
python scripts/convert_eval_to_csv.py \
  --outputs-dir outputs/ \
  --out-dir csv_outputs/
Always run inference on the test split, which was held out during training and hyperparameter selection. Do not evaluate on the validation split if it was used to tune early stopping or other training decisions — doing so inflates reported scores and undermines the integrity of the benchmark.

Build docs developers (and LLMs) love