This repo contains only the LoRA adapter (~20MB), not the full merged weights. Load it on top of the base model as shown below — this keeps the download small and lets you swap adapters on one base model in memory.
Intended use
Power medication reconciliation systems, pharmacovigilance pipelines.
Direct use
Paste a sentence mentioning a medication, get structured JSON entities back.
Downstream use
Feed extracted entities into a medication reconciliation tool or adverse-event reporting pipeline.
Out of scope
Drug interaction checking or dosage safety validation — this model extracts entities, it does not assess clinical appropriateness.
This model is not a substitute for a certified medical professional's judgment. Output should be reviewed by a qualified person before being used in a clinical or billing decision.
Quickstart
Option A — Transformers + PEFT
python
1from transformers import AutoModelForCausalLM, AutoTokenizer
2from peft import PeftModel
3import torch
45base_model ="unsloth/Qwen2.5-1.5B-Instruct"6adapter ="AmareshHebbar/pharmacy-ner-qwen25-1b"78tokenizer = AutoTokenizer.from_pretrained(base_model)9model = AutoModelForCausalLM.from_pretrained(10 base_model,11 torch_dtype=torch.bfloat16,12 device_map="auto",13)14model = PeftModel.from_pretrained(model, adapter)1516messages =[17{"role":"system","content":"You are a pharmacy NLP system. Extract drug name, dosage, frequency, route of administration, and indication from the text."},18{"role":"user","content":"Administer Vancomycin 1.5g IV every 12 hours for MRSA bacteraemia."},19]20inputs = tokenizer.apply_chat_template(messages, return_tensors="pt", add_generation_prompt=True).to(model.device)21outputs = model.generate(inputs, max_new_tokens=128, temperature=0.1, do_sample=True)22print(tokenizer.decode(outputs[0][inputs.shape[1]:], skip_special_tokens=True))
1from unsloth import FastLanguageModel
23model, tokenizer = FastLanguageModel.from_pretrained(4 model_name="AmareshHebbar/pharmacy-ner-qwen25-1b",5 max_seq_length=512,6 load_in_4bit=True,7)8FastLanguageModel.for_inference(model)910messages =[11{"role":"system","content":"You are a pharmacy NLP system. Extract drug name, dosage, frequency, route of administration, and indication from the text."},12{"role":"user","content":"Patient is on Warfarin 5mg orally once daily for atrial fibrillation."},13]14prompt = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)15inputs = tokenizer(prompt, return_tensors="pt").to("cuda")16outputs = model.generate(**inputs, max_new_tokens=128, temperature=0.1, do_sample=True)17print(tokenizer.decode(outputs[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True))
Option C — vLLM (production serving, OpenAI-compatible)
1from openai import OpenAI
23client = OpenAI(base_url="http://localhost:8000/v1", api_key="not-needed")4response = client.chat.completions.create(5 model="pharmacy-ner-qwen25-1b",6 messages=[7{"role":"system","content":"You are a pharmacy NLP system. Extract drug name, dosage, frequency, route of administration, and indication from the text."},8{"role":"user","content":"Morphine sulphate 10mg SC PRN every 4 hours for severe cancer pain."},9],10 temperature=0.1,11)12print(response.choices[0].message.content)
Option D — GGUF / llama.cpp (CPU / edge inference)
This repo ships LoRA adapter weights, not a pre-merged GGUF. To run on llama.cpp, merge first:
Trained on 3,500 examples extracted from bigbio/drugprot — biomedical abstracts with drug-protein interaction annotations (source). No synthetic or LLM-generated training data — every example pairs real-world input with its authoritative output.
Split
Rows
Train
2,800
Validation
350
Test
350
Full extraction pipeline documented on the dataset card.
Data recency. Training data reflects a specific snapshot in time (CMS FY2026 / dataset publish date). Codes, rates, and rules referenced may become outdated as source authorities issue updates — always cross-check against the live authoritative source before high-stakes use.
Failure mode. Like any LLM, this model can produce a plausible-sounding but incorrect output, especially on rare, ambiguous, or highly compound real-world cases that fall outside the training distribution. It does not know when it's wrong.
Language. English-language input only (Hindi-medical model excepted, where Hindi system prompts are used but underlying clinical reasoning data is largely English-sourced).
Not a regulated medical device. This model has not been validated, cleared, or approved by any regulatory body (FDA, CDSCO, or equivalent) as a medical device or clinical decision support tool. It is a research/engineering artifact.
Misapplication risk. Do not use this model as the sole basis for a clinical, billing, or compliance decision affecting a real patient or claim. Do not deploy in an emergency triage context without a human-in-the-loop and clear escalation paths.
FAQ
Q: Can I merge the adapter into the base model for faster inference?
Yes — use model.merge_and_unload() after loading with PEFT, or use Unsloth's save_pretrained_merged() method.
Q: Why QLoRA instead of full fine-tuning?
The base model already has strong language and medical knowledge from pretraining. QLoRA adapts only ~0.5-1% of parameters, which is enough to specialize the output format and domain without the cost or overfitting risk of full fine-tuning.
Q: Can I fine-tune this further on my own data?
Yes, this adapter can be used as a starting checkpoint for continued fine-tuning. Note this may require merging first depending on your training framework.
Q: Why is the output format so strict?
Each task was trained on a fixed system prompt and consistent output structure. Following the documented system prompt closely (see Quickstart above) gives the most reliable results — deviating from it may produce inconsistent formatting.
Q: Does this model store or transmit my input data?
No. Like any open-weight model, all inference happens locally on your own infrastructure (or wherever you deploy it) — nothing is sent back to the model author.
Troubleshooting
Symptom
Likely cause
Fix
ValueError: padding_token not set
Base tokenizer has no pad token
Set tokenizer.pad_token = tokenizer.eos_token before inference
Garbled / repeated output
Wrong chat template applied
Make sure you use tokenizer.apply_chat_template, not a raw string prompt
CUDA OOM on load
Insufficient VRAM
Use load_in_4bit=True (already default above) or reduce max_seq_length
Adapter loads but ignores fine-tuning
Base model mismatch
Confirm you loaded the exact base listed above — adapters are not portable across different base models or quantizations