DualModel — Dual AI-Model Cooperative Inference Framework
A local AI model + a cloud AI model, working together via Gate routing and Interrupter monitoring.
User Input
│
▼
┌───────┐ Route Decision ┌───────────────┐
│ Gate │ ────────────────► │ Local Model │ ◄── Qwen2.5 (0.5B/1.5B/7B)
│ Router │ └───────┬───────┘
└───────┘ │
│ ◄──── Switch Signal ────── │ token-by-token
▼ ▼
┌─────────────────┐ ┌───────────────┐
│ Interrupter │ ◄────── │ Cloud Model │ ◄── DeepSeek / OpenAI API
│ Monitor │ └───────────────┘
└────────┬────────┘
│ Quality degradation → triggers Gate re-route
▼
Model switch (with context compression)
Quick Start
1. Install
# Method 1: pip install (recommended for beginners)
pip install dualmodel # core
pip install "dualmodel[all]" # full features (train + api)
pip install "dualmodel[tray]" # with system tray
# Method 2: git clone (for developers)
git clone https://github.com/stevenwang15/dualmodel.git
cd dualmodel
pip install -e . # editable install
2. Set API Key
export DEEPSEEK_API_KEY="sk-your-key"
# Windows PowerShell:
# $env:DEEPSEEK_API_KEY = "sk-your-key"
No API Key? No problem — the system falls back to mock responses in
apimode.
3. Start the Web UI
python -m dualmodel --model api
Open http://localhost:8765 in your browser.
4. Start with a Local Model
# 0.5B model (~1GB, runs on CPU)
python -m dualmodel --model 0.5B
# 1.5B model (~3GB)
python -m dualmodel --model 1.5B
# 7B model (~15GB, requires GPU)
python -m dualmodel --model 7B
CLI Options
| Argument | Description | Default |
|---|---|---|
--model, -m |
Local model size: api / 0.5B / 1.5B / 7B |
api |
--port, -p |
API server port | 8765 |
--host, -H |
Listen address | 0.0.0.0 |
--verbose, -v |
Enable debug logging | false |
Model Download
Models are downloaded on demand from ModelScope (fast in China) when you first use a local model size. You can also manage downloads through the web UI:
http://localhost:8765/model-downloads
The download page shows real-time progress and allows you to delete cached models.
Running Modes
| Mode | Setting | Description | Best for |
|---|---|---|---|
| API Mode | --model api |
Zero download, no GPU needed. Uses cloud API or mock responses. | First try, quick demo |
| Lightweight | --model 0.5B or 1.5B |
Model ~1-3GB, runs on CPU/Mac M-series | Daily Q&A |
| Standard | --model 7B |
Requires GPU (~16GB VRAM) | Local inference |
How It Works
DualModel's core is the Gate + Interrupter dual-component system:
-
Gate Router — Analyzes user input and selects the best model (local or cloud). Supports keyword rules, semantic embedding routing, and trained model routing.
-
Interrupter Monitor — Monitors each generated token's confidence and entropy. Uses a sliding window to detect quality degradation. Performs semantic coherence checks. Triggers model switch when issues are found.
-
Model Switch — Automatically compresses context during switching to prevent token bloat. Includes a cooldown period to prevent thrashing. Falls back to the other model if one fails.
Environment Variables
| Variable | Description | Default |
|---|---|---|
DEEPSEEK_API_KEY |
Cloud API key | "" |
LOCAL_MODEL_SIZE |
Model size: api / 0.5B / 1.5B / 7B |
7B |
LOCAL_DEVICE |
Device: auto / cuda / mps / cpu |
auto |
LOCAL_MAX_LENGTH |
Max generation length (local) | 2048 |
LOCAL_PRELOAD |
Preload model on startup | false |
LOCAL_WARMUP |
Run warmup inference | true |
CLOUD_API_BASE |
Cloud API base URL | https://api.deepseek.com/v1 |
CLOUD_API_KEY |
Cloud API key (overrides DEEPSEEK_API_KEY) | "" |
CLOUD_MODEL_NAME |
Cloud model name | deepseek-chat |
ENABLE_THINKING |
Enable thinking/reasoning mode | true |
TOOL_CALL_ENABLED |
Enable function calling | true |
API_HOST |
Server listen address | 0.0.0.0 |
API_PORT |
Server port | 8765 |
Full config reference: dualmodel/config.py.
Project Structure
dualmodel/
├── __init__.py # Package entry, version 0.2.2
├── __main__.py # CLI entry: python -m dualmodel
├── api_server.py # OpenAI-compatible API server + Web UI
├── config.py # Configuration (env vars, dataclass)
├── gate.py # Gate router
├── interrupter.py # Interrupter monitor
├── pipeline.py # Main inference pipeline
├── local_model.py # Local model wrapper (HuggingFace / ModelScope)
├── cloud_model.py # Cloud API wrapper (OpenAI format)
├── utils.py # Utilities
├── train/ # Training module
│ ├── generate_data.py
│ ├── train_gate.py
│ └── train_interrupter.py
├── trained_models/ # Pre-trained models
│ ├── gate_model.pt
│ └── interrupter_model.pt
├── tray.py # System tray (macOS/Windows)
├── app.py # Gradio Web UI (legacy)
└── demo.py # CLI demo (legacy)
Dependencies
| Dependency | Use | Install |
|---|---|---|
| torch >= 2.1.0 | Deep learning framework | Core |
| transformers >= 4.36.0 | HF model loading | Core |
| openai >= 1.6.0 | Cloud API calls | Core |
| numpy | Scientific computing | Core |
| fastapi | API server | pip install dualmodel[api] |
| uvicorn | ASGI server | pip install dualmodel[api] |
| modelscope | Model download (China) | Core |
| sentence-transformers | Semantic encoding (training) | pip install dualmodel[train] |
| scikit-learn | ML tools (training) | pip install dualmodel[train] |
# Install all dependencies
pip install -e .[all]
Training Custom Models
DualModel supports training custom Gate and Interrupter models:
# 1. Generate training data
python -m dualmodel.train.generate_data
# 2. Train Gate model
python -m dualmodel.train.train_gate
# 3. Train Interrupter model
python -m dualmodel.train.train_interrupter
Trained models are saved to dualmodel/trained_models/ and loaded automatically on startup.
License
Apache 2.0
Tips
- First time? Run
python -m dualmodel --model api— zero downloads, instant start. - No GPU? Use
--model api— everything goes through the cloud API. - Different API provider? Change
CLOUD_API_BASEandCLOUD_MODEL_NAMEto work with any OpenAI-compatible API (DeepSeek, OpenAI, Qwen, etc.).
Metadata
Release files for dualmodel 0.2.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| dualmodel-0.2.3.tar.gz | 83.6 MB | Without provenance | Details for dualmodel-0.2.3.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| dualmodel-0.2.3-py3-none-any.whl | Python 3 | none | any | Details for dualmodel-0.2.3-py3-none-any.whl |
Total release size: 167.2 MB
Release files / dualmodel-0.2.3.tar.gz
| Download URL | dualmodel-0.2.3.tar.gz |
|---|---|
| Size | 83.6 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d7835985fa6cc7c8af360a008b2e34b8e8e8541695b591a49bc4bf56f6d674cc
|
|
BLAKE2b-256 checksum How to use checksums |
60f070e4150f81f7dda828bb6ea40513e7a2fc029ca6e5db0713107b25e50efb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|
Release files / dualmodel-0.2.3-py3-none-any.whl
| Download URL | dualmodel-0.2.3-py3-none-any.whl |
|---|---|
| Size | 83.6 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
66c7f9e6a311f7c714e31dbf793a623e47cd242ce1029bda829f8ec337cdbe58
|
|
BLAKE2b-256 checksum How to use checksums |
4cd9d20d529ff8947fb6f029ac5356ac7d1272c6336dfb52b2e6b019d3933a7f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|
Security for dualmodel 0.2.3
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.