LoRA and aLoRA adapters
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[cli]". Training requires a GPU or
Apple Silicon Mac with sufficient VRAM for the chosen base model. Uploading requires a
Hugging Face account.
Backend note: Custom-trained adapters can only be loaded into
LocalHFBackend. They do not work with Ollama, OpenAI, or other remote backends.Granite Switch models ship with pre-trained intrinsic adapters embedded in the model weights, which can be used via
OpenAIBackendwithload_embedded_adapters=True. See Intrinsics for details.
LoRA vs aLoRA
Both adapter types fine-tune a base model on your data. The difference is inference cost:
| LoRA | aLoRA | |
|---|---|---|
| Inference overhead | Processes full context each call | Activated at a single token — minimal overhead |
| Best for | General fine-tuning | Fast inner-loop checks, requirement validation |
| Training time | Similar | Similar |
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 classifylabel— 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
| Flag | Type | Default | Description |
|---|---|---|---|
datafile | str | required | Path to .jsonl training file |
--basemodel | str | required | Hugging Face model ID or local path |
--outfile | str | required | Directory to save adapter weights |
--adapter | str | alora | Adapter type: alora or lora |
--device | str | auto | Device: auto, cpu, cuda, or mps |
--epochs | int | 6 | Number of training epochs |
--learning-rate | float | 6e-6 | Learning rate |
--batch-size | int | 2 | Per-device batch size |
--max-length | int | 1024 | Max tokenized sequence length |
--grad-accum | int | 4 | Gradient accumulation steps |
--promptfile | str | None | JSON 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 | CLI Reference