AI-powered medical assistant integrating local LLM inference with OpenEMR for patient data-aware clinical decision support.
Note: This module is for research and educational purposes. Always verify AI-generated information and consult healthcare professionals for clinical decisions.
┌─────────────────────────────────────────────────────────────────┐
│ OpenEMR Web Interface │
│ (llm.php frontend) │
└─────────────────────┬───────────────────────────────────────────┘
│ HTTP/JSON
┌─────────────────────▼───────────────────────────────────────────┐
│ Python Flask Server │
│ (llm_server.py) │
│ ┌─────────────┬─────────────┬──────────────┬────────────────┐ │
│ │ llama.cpp │ Ollama │ OpenAI │ HuggingFace │ │
│ │ Backend │ Backend │ Compat │ Backend │ │
│ └──────┬──────┴──────┬──────┴──────┬───────┴───────┬────────┘ │
└─────────┼─────────────┼─────────────┼───────────────┼──────────┘
│ │ │ │
┌─────▼─────┐ ┌─────▼─────┐ ┌─────▼─────┐ ┌──────▼──────┐
│ llama.cpp │ │ Ollama │ │ vLLM/ │ │ Transformers │
│ Server │ │ Server │ │ LocalAI │ │ Library │
└───────────┘ └───────────┘ └───────────┘ └──────────────┘
# Clone into OpenEMR custom modules directory
cd /var/www/html/openemr/interface/modules/custom_modules/
git clone https://github.com/SolshineCode/OpenEMR_LLM_Module.git llm
cd llm
# Install Python dependencies
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
# Copy and configure environment
cp .env.example .env
nano .env # Edit settings
# Install llama.cpp
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp && make -j
# Download a medical model (example: Llama 3.2)
./llama-cli --hf-repo bartowski/Llama-3.2-1B-Instruct-GGUF \
--hf-file Llama-3.2-1B-Instruct-Q4_K_M.gguf \
--model-only
# Start the server
./llama-server -m Llama-3.2-1B-Instruct-Q4_K_M.gguf \
--port 8080 --ctx-size 4096
Configure in .env:
LLM_BACKEND=llamacpp
LLAMACPP_SERVER_URL=http://localhost:8080
# Install Ollama
curl -fsSL https://ollama.com/install.sh | sh
# Pull a model
ollama pull llama3.2
# or for medical: ollama pull medllama2
Configure in .env:
LLM_BACKEND=ollama
OLLAMA_HOST=http://localhost:11434
OLLAMA_MODEL=llama3.2
cd /var/www/html/openemr/interface/modules/custom_modules/llm
source venv/bin/activate
python llm_server.py
For production, use Gunicorn:
gunicorn -w 4 -b 127.0.0.1:5000 llm_server:app
All configuration is done via environment variables. Copy .env.example to .env and edit:
FLASK_HOST=127.0.0.1
FLASK_PORT=5000
FLASK_DEBUG=false
# Options: llamacpp, ollama, openai, huggingface
LLM_BACKEND=llamacpp
# llama.cpp settings
LLAMACPP_SERVER_URL=http://localhost:8080
# Ollama settings
OLLAMA_HOST=http://localhost:11434
OLLAMA_MODEL=llama3.2
OPENEMR_BASE_URL=https://localhost:9300
OPENEMR_CLIENT_ID=your-client-id
OPENEMR_CLIENT_SECRET=your-secret
MAX_TOKENS=512
TEMPERATURE=0.7
SYSTEM_PROMPT=You are a helpful medical assistant...
To enable patient data context, register an OAuth2 client in OpenEMR:
user/Patient.rsuser/Encounter.rsuser/Observation.rsuser/Condition.rsuser/AllergyIntolerance.rsuser/MedicationRequest.rs.env fileCreate a custom medical model optimized for your use case:
cd fine_tuning
pip install -r requirements-unsloth.txt
# Train on medical QA data
python train_medical_llm.py \
--base_model unsloth/Llama-3.2-1B-Instruct \
--dataset medmcqa \
--output_dir ./models/medical_adapter \
--epochs 1
See fine_tuning/README.md for detailed instructions.
| Endpoint | Method | Description |
|---|---|---|
/health | GET | Server health check |
/config | GET | Get current configuration |
/generate | POST | Generate LLM response |
/models | GET | List available models |
/feedback | POST | Submit response feedback |
/patient/<id>/summary | GET | Get patient summary |
curl -X POST http://localhost:5000/generate \
-H "Content-Type: application/json" \
-d '{
"prompt": "What are the common symptoms of diabetes?",
"patient_id": "12345",
"include_patient_data": true,
"max_tokens": 512
}'
llm/
├── llm_server.py # Main Flask server
├── config.py # Configuration management
├── openemr_client.py # OpenEMR FHIR API client
├── llm.php # Frontend interface
├── module.info # OpenEMR module metadata
├── module.config.php # OpenEMR module configuration
├── requirements.txt # Python dependencies
├── .env.example # Environment configuration template
├── llm_backends/ # LLM backend implementations
│ ├── __init__.py
│ ├── base.py # Abstract base class
│ ├── llamacpp.py # llama.cpp server backend
│ ├── ollama.py # Ollama backend
│ ├── openai_compat.py # OpenAI-compatible backend
│ └── huggingface.py # HuggingFace Transformers backend
├── utils/ # Utility modules
│ ├── __init__.py
│ ├── logging_config.py # Structured logging setup
│ └── security.py # Input sanitization, PHI anonymization
└── fine_tuning/ # Model fine-tuning tools
├── README.md
├── requirements-unsloth.txt
├── train_medical_llm.py
└── sample_training_data.json
ANONYMIZE_PATIENT_DATA=true in production| Model | Source | Size | Notes |
|---|---|---|---|
| Llama 3.2 | Ollama/llama.cpp | 1-3B | Good general model |
| Mistral 7B | Ollama/llama.cpp | 7B | High quality |
| MedLlama2 | Ollama | 7B | Medical fine-tuned |
| BioGPT | HuggingFace | 1.5B | Biomedical domain |
| Meditron | HuggingFace | 7-70B | Clinical domain |
.env configuration is correctlogs/app.logMAX_TOKENS graduallyContributions are welcome! Please:
GNU General Public License v3 (GPL-3.0)
This module is for research and educational purposes only. It should not be used as the sole basis for medical decisions. Always consult qualified healthcare professionals for clinical decisions.
The AI-generated responses may contain errors or outdated information. Users are responsible for verifying all information before clinical use.
37 commits
1 commits
Python
77.0%
PHP
23.0%
AI-powered medical assistant integrating local LLM inference with OpenEMR for patient data-aware clinical decision support.
Note: This module is for research and educational purposes. Always verify AI-generated information and consult healthcare professionals for clinical decisions.
┌─────────────────────────────────────────────────────────────────┐
│ OpenEMR Web Interface │
│ (llm.php frontend) │
└─────────────────────┬───────────────────────────────────────────┘
│ HTTP/JSON
┌─────────────────────▼───────────────────────────────────────────┐
│ Python Flask Server │
│ (llm_server.py) │
│ ┌─────────────┬─────────────┬──────────────┬────────────────┐ │
│ │ llama.cpp │ Ollama │ OpenAI │ HuggingFace │ │
│ │ Backend │ Backend │ Compat │ Backend │ │
│ └──────┬──────┴──────┬──────┴──────┬───────┴───────┬────────┘ │
└─────────┼─────────────┼─────────────┼───────────────┼──────────┘
│ │ │ │
┌─────▼─────┐ ┌─────▼─────┐ ┌─────▼─────┐ ┌──────▼──────┐
│ llama.cpp │ │ Ollama │ │ vLLM/ │ │ Transformers │
│ Server │ │ Server │ │ LocalAI │ │ Library │
└───────────┘ └───────────┘ └───────────┘ └──────────────┘
# Clone into OpenEMR custom modules directory
cd /var/www/html/openemr/interface/modules/custom_modules/
git clone https://github.com/SolshineCode/OpenEMR_LLM_Module.git llm
cd llm
# Install Python dependencies
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
# Copy and configure environment
cp .env.example .env
nano .env # Edit settings
# Install llama.cpp
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp && make -j
# Download a medical model (example: Llama 3.2)
./llama-cli --hf-repo bartowski/Llama-3.2-1B-Instruct-GGUF \
--hf-file Llama-3.2-1B-Instruct-Q4_K_M.gguf \
--model-only
# Start the server
./llama-server -m Llama-3.2-1B-Instruct-Q4_K_M.gguf \
--port 8080 --ctx-size 4096
Configure in .env:
LLM_BACKEND=llamacpp
LLAMACPP_SERVER_URL=http://localhost:8080
# Install Ollama
curl -fsSL https://ollama.com/install.sh | sh
# Pull a model
ollama pull llama3.2
# or for medical: ollama pull medllama2
Configure in .env:
LLM_BACKEND=ollama
OLLAMA_HOST=http://localhost:11434
OLLAMA_MODEL=llama3.2
cd /var/www/html/openemr/interface/modules/custom_modules/llm
source venv/bin/activate
python llm_server.py
For production, use Gunicorn:
gunicorn -w 4 -b 127.0.0.1:5000 llm_server:app
All configuration is done via environment variables. Copy .env.example to .env and edit:
FLASK_HOST=127.0.0.1
FLASK_PORT=5000
FLASK_DEBUG=false
# Options: llamacpp, ollama, openai, huggingface
LLM_BACKEND=llamacpp
# llama.cpp settings
LLAMACPP_SERVER_URL=http://localhost:8080
# Ollama settings
OLLAMA_HOST=http://localhost:11434
OLLAMA_MODEL=llama3.2
OPENEMR_BASE_URL=https://localhost:9300
OPENEMR_CLIENT_ID=your-client-id
OPENEMR_CLIENT_SECRET=your-secret
MAX_TOKENS=512
TEMPERATURE=0.7
SYSTEM_PROMPT=You are a helpful medical assistant...
To enable patient data context, register an OAuth2 client in OpenEMR:
user/Patient.rsuser/Encounter.rsuser/Observation.rsuser/Condition.rsuser/AllergyIntolerance.rsuser/MedicationRequest.rs.env fileCreate a custom medical model optimized for your use case:
cd fine_tuning
pip install -r requirements-unsloth.txt
# Train on medical QA data
python train_medical_llm.py \
--base_model unsloth/Llama-3.2-1B-Instruct \
--dataset medmcqa \
--output_dir ./models/medical_adapter \
--epochs 1
See fine_tuning/README.md for detailed instructions.
| Endpoint | Method | Description |
|---|---|---|
/health | GET | Server health check |
/config | GET | Get current configuration |
/generate | POST | Generate LLM response |
/models | GET | List available models |
/feedback | POST | Submit response feedback |
/patient/<id>/summary | GET | Get patient summary |
curl -X POST http://localhost:5000/generate \
-H "Content-Type: application/json" \
-d '{
"prompt": "What are the common symptoms of diabetes?",
"patient_id": "12345",
"include_patient_data": true,
"max_tokens": 512
}'
llm/
├── llm_server.py # Main Flask server
├── config.py # Configuration management
├── openemr_client.py # OpenEMR FHIR API client
├── llm.php # Frontend interface
├── module.info # OpenEMR module metadata
├── module.config.php # OpenEMR module configuration
├── requirements.txt # Python dependencies
├── .env.example # Environment configuration template
├── llm_backends/ # LLM backend implementations
│ ├── __init__.py
│ ├── base.py # Abstract base class
│ ├── llamacpp.py # llama.cpp server backend
│ ├── ollama.py # Ollama backend
│ ├── openai_compat.py # OpenAI-compatible backend
│ └── huggingface.py # HuggingFace Transformers backend
├── utils/ # Utility modules
│ ├── __init__.py
│ ├── logging_config.py # Structured logging setup
│ └── security.py # Input sanitization, PHI anonymization
└── fine_tuning/ # Model fine-tuning tools
├── README.md
├── requirements-unsloth.txt
├── train_medical_llm.py
└── sample_training_data.json
ANONYMIZE_PATIENT_DATA=true in production| Model | Source | Size | Notes |
|---|---|---|---|
| Llama 3.2 | Ollama/llama.cpp | 1-3B | Good general model |
| Mistral 7B | Ollama/llama.cpp | 7B | High quality |
| MedLlama2 | Ollama | 7B | Medical fine-tuned |
| BioGPT | HuggingFace | 1.5B | Biomedical domain |
| Meditron | HuggingFace | 7-70B | Clinical domain |
.env configuration is correctlogs/app.logMAX_TOKENS graduallyContributions are welcome! Please:
GNU General Public License v3 (GPL-3.0)
This module is for research and educational purposes only. It should not be used as the sole basis for medical decisions. Always consult qualified healthcare professionals for clinical decisions.
The AI-generated responses may contain errors or outdated information. Users are responsible for verifying all information before clinical use.
37 commits
1 commits
Python
77.0%
PHP
23.0%