Skip to main content
Off-the-shelf language models sometimes fail on domain-specific tasks — particularly requirement validation over proprietary terminology or specialized classification schemes not well-represented in general training data. Mellea lets you train a LoRA or aLoRA adapter on your own labeled dataset and use it as a requirement validator in any Mellea program. Prerequisites: pip install mellea, m CLI available. Training requires a GPU or Apple Silicon Mac with sufficient VRAM for the chosen base model. Uploading requires a Hugging Face account.
Backend note: Trained adapters can only be loaded into LocalHFBackend. They do not work with Ollama, OpenAI, or other remote backends.

LoRA vs aLoRA

Both adapter types fine-tune a base model on your data. The difference is inference cost:
LoRAaLoRA
Inference overheadProcesses full context each callActivated at a single token — minimal overhead
Best forGeneral fine-tuningFast inner-loop checks, requirement validation
Training timeSimilarSimilar
For requirement validation in Mellea (short binary checks inside a generation loop), aLoRA is the better choice. Use --adapter lora if you need a more general fine-tune and can absorb the inference cost.

Data format

Training data is a .jsonl file with one JSON object per line. Each object must have:
  • item — the input text to classify
  • label — the string classification label
{"item": "Observed black soot on intake. Seal seems compromised under thermal load.", "label": "piston_rings"}
{"item": "Rotor misalignment caused torsion on connecting rod. High vibration at 3100 RPM.", "label": "connecting_rod"}
{"item": "Combustion misfire traced to a cracked mini-carburetor flange.", "label": "mini_carburetor"}
{"item": "Stembolt makes a whistling sound and does not complete the sealing process.", "label": "no_failure"}
Labels can be any strings. The adapter learns to predict the label from the item text.

Train an adapter

m alora train data.jsonl \
  --basemodel ibm-granite/granite-3.2-8b-instruct \
  --outfile ./checkpoints/my_adapter \
  --adapter alora \
  --epochs 6 \
  --learning-rate 6e-6 \
  --batch-size 2 \
  --max-length 1024 \
  --grad-accum 4
The trained adapter weights are saved to ./checkpoints/my_adapter/.

Parameters

FlagTypeDefaultDescription
datafilestrrequiredPath to .jsonl training file
--basemodelstrrequiredHugging Face model ID or local path
--outfilestrrequiredDirectory to save adapter weights
--adapterstraloraAdapter type: alora or lora
--devicestrautoDevice: auto, cpu, cuda, or mps
--epochsint6Number of training epochs
--learning-ratefloat6e-6Learning rate
--batch-sizeint2Per-device batch size
--max-lengthint1024Max tokenized sequence length
--grad-accumint4Gradient accumulation steps
--promptfilestrNoneJSON file overriding the invocation prompt
The default invocation prompt is <|start_of_role|>check_requirement<|end_of_role|>. Provide --promptfile only if your adapter needs a different prompt format. The file must contain {"invocation_prompt": "..."}.

Upload to Hugging Face

huggingface-cli login  # one-time setup

m alora upload ./checkpoints/my_adapter \
  --name your-org/my-adapter
This creates the Hugging Face repository if it does not exist and uploads the adapter weights. Requires HF_TOKEN set or a prior huggingface-cli login.
Warning: Before uploading to a public repository, review whether your training data includes proprietary, confidential, or personal information. Language models can memorize details from small domain-specific datasets.
If you intend to use the adapter as a Mellea intrinsic (so that it can be loaded by model ID rather than local path), pass --intrinsic and provide an io.yaml file:
m alora upload ./checkpoints/my_adapter \
  --name your-org/my-adapter \
  --intrinsic \
  --io-yaml ./io.yaml

Use the adapter in Mellea

Load the trained adapter into a LocalHFBackend using CustomIntrinsicAdapter:
from mellea.backends.huggingface import LocalHFBackend
from mellea.backends.adapters.adapter import CustomIntrinsicAdapter
from mellea.stdlib.context import ChatContext
from mellea import MelleaSession
from mellea.stdlib.requirements import req

backend = LocalHFBackend(model_id="ibm-granite/granite-3.2-8b-instruct")

adapter = CustomIntrinsicAdapter(
    model_id="your-org/my-adapter",       # HF repo ID or local checkpoint path
    base_model_name="granite-3.2-8b-instruct",
)
backend.add_adapter(adapter)

m = MelleaSession(backend, ctx=ChatContext())

failure_check = req("The failure mode must not be 'no_failure'.")
result = m.instruct(
    "Write a triage summary based on this technician note: {{note}}",
    user_variables={"note": "High vibration at 3100 RPM, connecting rod suspected."},
    requirements=[failure_check],
)
print(str(result))
# Output will vary — LLM responses depend on model and temperature.
When backend.add_adapter() is called, Mellea automatically routes requirement validation through the adapter for any req() calls on that session. The adapter runs at the check_requirement prompt position — fast, with minimal context overhead.

Disable adapter validation

To run without adapter validation (for benchmarking or debugging):
backend.default_to_constraint_checking_alora = False
Set it back to True to re-enable. This flag is per-backend instance and does not affect other sessions. See also: Intrinsics | The Requirements System | Write Custom Verifiers