Skip to main content

aim — AI Model Manager

Unified CLI for managing AI models across multiple inference engines.

Features

  • Multi-engine support: Ollama, Hugging Face, MLX (omlx), ComfyUI, Whisper, Coqui TTS, SparkTTS, Piper, Fish Speech
  • Canonical Store: Models organized by category in ~/AI/store/{category}/{model_id}/, with symlinks/hardlinks back to engine directories
  • Deduplication: Detect and deduplicate identical model files across engines via hardlinks
  • Registry: Track all models in a single JSON registry with metadata, provenance, and provision info

Docs

  • Download PRD: docs/download-prd.md
  • Download implementation plan: docs/download-implementation-plan.md
  • Download JSON contract: docs/download-json-contract.md

Install

# Symlink to PATH
ln -sf "$(pwd)/aim.py" ~/.local/bin/aim
chmod +x aim.py

Usage

# Scan all engines and register models
aim scan

# Re-classify model categories from each model's shipped metadata (no delete+rescan)
aim recategorize --all --dry-run     # preview every change
aim recategorize --all               # apply

# List registered models
aim list
aim list --engine comfyui --sort size
aim list --json                      # JSON array output

# Show model details
aim info <model_id>
aim info <model_id> --json           # full metadata as JSON

# Resolve model to absolute path (for inference)
aim resolve <model_id>               # prints absolute path
aim resolve <model_id> --json        # full metadata + path + resolved_file
aim resolve <model_id> --engine comfyui  # prefer engine provision path

# Organize models into canonical store (preview)
aim organize

# Organize all non-CAS models
aim organize --all

# Organize a single model
aim organize <model_id>

# Download a model
aim download hf:org/repo
aim download ollama:model:tag
aim download hf:org/repo --json

# Non-interactive / headless backend auto-install (e.g. called by another service):
#   a missing backend (ModelScope CLI, etc.) is normally confirmed interactively [y/N].
#   To auto-install without a prompt, opt in via ANY of:
#     aim download ms:org/repo -y           # flag
#     AIM_ASSUME_YES=1 aim download ms:...   # env var (set once in the service env)
#     # or set  "defaults": {"auto_install_backend": true}  in ~/.aim/config.json
#   Headless with NO opt-in: aim prints a clear stderr error (missing tool + how to enable)
#   and fails — it never silently hangs or aborts. With --json it returns BACKEND_NOT_FOUND.
aim download status <job_id> --json
aim download cancel <job_id>
aim download hf:org/repo --category llm/chat
aim download hf:org/repo --path /custom/path
aim download url:https://example.com/model.bin --no-progress
aim download url:https://example.com/model.bin --no-resume
aim download hf:org/repo --proxy http://127.0.0.1:7890 --retry 3 --retry-backoff 1.5

# Import/register existing local model path
aim import /path/to/local/model-dir --id my-model --category llm/chat

# Ingest a native-cache model (HF/Ollama/ModelScope) into the store + rebuild its load shim
aim ingest <model_id>                 # one model: copy real files flat into store/, rebuild the tool's load shim
aim ingest --all-native               # ingest all native_cas (HF/Ollama/MS) models
aim ingest <model_id> --dry-run       # preview, change nothing
aim ingest <model_id> --keep-native   # keep original native bytes (default reclaims them)
aim convert <model_id>                # deprecated alias -> ingest
aim verify --fix                      # also rebuilds storage shims from the recorded annotation

# Ingestable sources now include single-file weights:
#   PyTorch Hub    ($TORCH_HOME/hub/checkpoints/*.pth)              -> aim ingest <torch-id>
#   openai-whisper (${XDG_CACHE_HOME:-~/.cache}/whisper/*.pt)       -> aim ingest <whisper-id>
# aim scan discovers them; ingest copies into store and leaves a file symlink so the tool still loads.

# Portable backup / restore (store/ + manifest; shims are regenerated on restore)
aim backup /Volumes/Backup/aim       # mirror store/ + write aim-backup.json (idempotent; re-runnable)
aim backup /Volumes/Backup/aim --verify
aim restore /Volumes/Backup/aim      # recreate store, rebuild tool shims for THIS machine, print env to set
aim restore /Volumes/Backup/aim --apply-env   # also write env to shell config

# Provision a model for an engine
aim provision <model_id> --engine comfyui

# Verify link integrity
aim verify
aim verify --fix

# Storage overview
aim status
aim status --by category

# Detect / manage download-source env vars (HF, Ollama, ModelScope, PyTorch Hub, Civitai, Git)
aim env show                          # detected vars + resolved cache dirs (read-only)
aim env show --json                   # machine-readable; secret values are masked
aim env path huggingface              # resolved cache dir for a source
aim env apply --shell zsh             # write ~/.aim/env.{sh,fish} + wire rc (one guarded line)
aim env apply --set HF_ENDPOINT=https://hf-mirror.com --set HF_HUB_ENABLE_HF_TRANSFER=1
aim env apply --dry-run               # preview, write nothing
aim env apply --service               # also print daemon-level (launchctl/systemd) env commands
aim sources list                      # sources, tool install state, env summary
aim sources install huggingface -y    # install a source's download tool

# Find duplicates
aim dedup
aim dedup --apply

# Find unregistered model files
aim orphans

JSON Output

aim list, aim info, and aim resolve support --json for programmatic integration. aim download --json emits JSONL progress events and a final JSON summary.

aim resolve <id> --json is the recommended single-call API — it returns the full model metadata (superset of aim info --json) plus two extra fields:

{
  "id": "whisper-large-v3-turbo",
  "name": "whisper-large-v3-turbo",
  "source": { "type": "local", "repo_id": "openai/whisper-large-v3-turbo" },
  "format": "pt",
  "size_bytes": 1617941637,
  "category": "asr/model",
  "engines": ["whisper"],
  // ... all other model fields ...
  "path": "/Users/you/AI/store/asr/model/whisper-large-v3-turbo",
  "resolved_file": "/Users/you/AI/store/asr/model/whisper-large-v3-turbo/large-v3-turbo.pt"
}
Field Description
path Absolute directory (or file) path, resolved via provision or canonical store
resolved_file Primary weight file inside the directory, or null for sharded / complex models

Download placement policy:

  1. --path has highest priority
  2. Else auto place under store/<category>/<model_id>/
  3. Missing category falls back to inferred category, then uncategorized

Download control flags:

  1. --no-progress: only final summary (especially useful with --json)
  2. --resume / --no-resume: toggle resume behavior
  3. --proxy --timeout --connect-timeout --retry --retry-backoff --max-speed --concurrency

resolved_file detection: scans top-level weight files (.safetensors, .pt, .pth, .gguf, .bin, .onnx). Single file → returned directly. Multiple → picks largest matching format. Sharded models (model-00001-of-00006) → null (load from directory).

Store Layout

~/AI/store/
├── asr/model/           — speech-to-text models (Whisper, Paraformer, SenseVoice …)
├── audio/
│   ├── vad/             — voice-activity detection (silero, fsmn-vad)
│   ├── codec/           — neural audio codecs (EnCodec, SNAC)
│   ├── punctuation/     — punctuation restoration
│   ├── speaker/         — speaker verification / diarization
│   └── emotion/         — speech-emotion recognition
├── image-gen/
│   ├── checkpoint/      — FLUX, SDXL checkpoints
│   ├── lora/            — LoRA weights
│   ├── text-encoder/    — CLIP, T5 encoders
│   └── vae/             — VAE models
├── llm/
│   ├── chat/            — LLM chat models
│   ├── embedding/       — embedding / sentence-transformer models
│   └── vision/          — multimodal / vision-language / "omni" models
└── tts/
    ├── model/           — TTS models
    └── vocoder/         — vocoder models

Model Classification

Every registered model gets a category (which store subtree it lives in). aim infers it from the metadata the model ships with, not by guessing from its name — trying the most authoritative signal first and recording which one decided it in category_source:

# Signal (read from the model directory) Example
1 HF README.md frontmatter pipeline_tag / tags / library_name automatic-speech-recognitionasr/model
2 ModelScope configuration.json task voice-activity-detectionaudio/vad
3 HF config.json architectures / model_type WhisperForConditionalGenerationasr/model; a vision_config/audio_configllm/vision
4 File-structure signatures diffusers model_index.jsonimage-gen/checkpoint; adapter_config.jsonimage-gen/lora
5 Repo-id keywords (best-effort) …/whisper-large-v3asr/model
6 Default llm/chat (recorded as a low-confidence guess)

Authority order of category_source: manual > pipeline_tag = ms_task > config_arch > file_sig > repo_keyword > default.

  • aim scan classifies newly-discovered models and self-heals a previously guessed category (default/repo_keyword) when a re-scan reads a stronger signal — never overwriting an authoritative or manual one.

  • aim recategorize re-classifies already-registered models in place (no delete + rescan):

    aim recategorize --all --dry-run   # preview every change
    aim recategorize <model-id>        # a single model
    aim recategorize --all             # apply (upgrades only; weaker signals are skipped)
    aim recategorize --all --force     # override even stronger / manual categories
    

Multimodal models (vision-language, audio-LLM, "omni") are classified by their true nature — llm/vision — even when an application happens to use them for a single modality (e.g. ASR). aim resolve is category-agnostic, so consumers keep resolving the same path across a recategorization.

How It Works

  1. aim scan discovers models in engine directories, registers them
  2. aim organize moves models into store/{category}/{id}/, replaces originals with:
    • Directories → symlink back to engine location
    • Files in shared dirs → hardlink back
  3. aim verify checks all links are intact
  4. aim provision creates links for a model in any supported engine

Configuration

Config is stored at ~/.aim/config.json. Registry at ~/.aim/registry.json.

Requirements

  • Python 3.10+
  • macOS / Linux
  • Optional: gh CLI, hfd.sh for downloads

Testing

# Run syntax check
make lint

# Run all tests (unit + e2e)
make test

# Run only unit tests
make test-unit

# Run only end-to-end tests
make test-e2e

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ai_model_manager-0.2.2.tar.gz (90.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ai_model_manager-0.2.2-py3-none-any.whl (63.5 kB view details)

Uploaded Python 3

File details

Details for the file ai_model_manager-0.2.2.tar.gz.

File metadata

  • Download URL: ai_model_manager-0.2.2.tar.gz
  • Upload date:
  • Size: 90.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for ai_model_manager-0.2.2.tar.gz
Algorithm Hash digest
SHA256 b2bb2eb95754198e323b246dd0493fec5fcbdf2abe04231aeb65b233d40462ef
MD5 dc4643debbd75066ceb170a50073ffb4
BLAKE2b-256 9c749da23d24695cc9a405806061ca24c21876a4d8058dbcc167370c1d9b8f94

See more details on using hashes here.

File details

Details for the file ai_model_manager-0.2.2-py3-none-any.whl.

File metadata

File hashes

Hashes for ai_model_manager-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 a38f84e38cf0cfe77dab1c683a88e82e5ebf8e7ffe5bc2d8a8b53d05a4731c5d
MD5 6d303d2fe1d20a688d33cb14cab08199
BLAKE2b-256 cde49ea2e27cb5414cd3421069b38aa80ee21a55bb53947109f038c3b7868863

See more details on using hashes here.

Release history Release notifications | RSS feed

0.3.0

2 files

This release

0.2.2 This release

2 files

0.2.1

2 files

0.2.0

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page