Skip to content

Repository files navigation

Local AI Image Gen

Fully offline AI image generation and editing for Mac Silicon (Apple MPS). No cloud. No API keys. No subscriptions. Everything runs on your machine.

Standalone project. Started as a fork of newideas99/ultra-fast-image-gen but has diverged significantly — Gradio replaced with a FastAPI backend + React UI, new features (batch img2img, depth maps, watermark removal, LoRA stacking, iterative inpainting), and a different architecture overall. Not intended to track upstream.


What it does

  • Text-to-image — generate images from a prompt
  • Image-to-image editing — upload a reference photo and transform it with natural language
  • Inpainting — draw a rectangle mask on any region and regenerate just that area
  • Multi-slot reference images — up to 6 reference images, each with its own mask and strength slider
  • Iterative multi-mask inpainting — chain multiple mask passes automatically (one per slot)
  • Video generation — text-to-video and image-to-video with LTX-Video
  • Multi-LoRA stacking — load up to 5 .safetensors LoRA adapters simultaneously, each with its own strength slider; the dropdown is filtered to only show LoRAs compatible with the active model
  • Batch img2img — point at a folder of images and run the current prompt + params over all of them automatically; gallery updates after each image
  • Upscaling — 4× single image or batch-folder upscale with any Spandrel-compatible model
  • Workflow save/load — save your full setup (model, params, reference images, masks) and reload it later
  • Gallery — browse recent outputs, drag them into reference slots, upscale or delete
  • Depth map generation — generate 16-bit DA3 depth maps directly from the Gallery; white = near, black = far
  • Auto-outpaint — automatically fill borders when the reference image is a different aspect ratio

Supported models

Model VRAM Notes
FLUX.2-klein-4B (4-bit SDNQ) < 8 GB @ 512 px Fastest FLUX — text + image editing
FLUX.2-klein-9B (4-bit SDNQ) ~12 GB @ 512 px Higher quality
FLUX.2-klein-4B (Int8) ~16 GB Alternative quantization
Z-Image Turbo (Quantized) ~8 GB Fastest overall — text-to-image only
Z-Image Turbo (Full) ~24 GB LoRA support
LTX-Video Text-to-video / image-to-video

Models are downloaded automatically the first time you select them. They are cached in ./models/.


Requirements

Minimum
Mac Apple Silicon (M1 or later) — macOS 13+
Python 3.11 or 3.12
RAM 16 GB recommended (more = better)
Disk ~20 GB per model

Quick start — Mac (1-click)

git clone https://github.com/KrissTos/off-line-Image-gen-mac.git
cd off-line-Image-gen-mac

Then double-click Launch.command in Finder.

The first launch installs all dependencies (~5 min). A browser tab opens automatically at http://localhost:7860.

Terminal lifecycle: The Terminal window that opens is managed automatically. When you close the browser tab the server shuts down and Terminal closes itself — you don't need to quit it manually. Refreshing the page reconnects within ~1 s and cancels the shutdown.


Manual start

# Install uv (package manager) if you don't have it
curl -LsSf https://astral.sh/uv/install.sh | sh

# Create venv and install deps
uv venv
source .venv/bin/activate
uv sync

# Build the frontend
cd frontend && npm install && npm run build && cd ..

# Start the server
python server.py --port 7860

Open http://localhost:7860 in your browser.

Dev mode (hot-reload frontend)

./Launch.command --dev
# FastAPI on :7861, Vite HMR on :5173

First run — model download

  1. Open the UI and select a model from the Model accordion in the sidebar
  2. Click Load Model — the model downloads from HuggingFace and is cached locally
  3. Some models are gated (require a free HuggingFace account + accepting terms):
    • Create an account at huggingface.co
    • Accept the model terms on the model page
    • Paste your Read token in Settings → HuggingFace Login

How the UI works

┌──────────────────────────────────────────────────────────┐
│  TopBar — model name · device · VRAM · status            │
├──────────────┬───────────────────────────────────────────┤
│              │  Canvas (result image / video)            │
│   Sidebar    ├───────────────────────────────────────────┤
│   (params)   │  Reference image slots + mask editor      │
│              ├───────────────────────────────────────────┤
│              │  Gallery (recent outputs)                 │
└──────────────┴───────────────────────────────────────────┘

Sidebar sections

Section What it does
Model Pick and load a model
Parameters Steps, guidance scale, seed, repeat count
Size Output resolution — presets change per model
LoRA Stack up to 5 LoRA adapters, each with its own strength; filtered by active model
Upscale 4× single image or batch folder
Batch Img2Img Process a whole folder of images with the current settings
Video LTX-Video settings (only visible with LTX model)
Depth Map Generate a 16-bit depth PNG for the current output image
Workflows Save / load your full setup

Reference image slots

  • Click + to add a reference image (upload, drag from gallery, or paste a URL)
  • Click the pencil icon to draw a rectangle mask — only that region will be regenerated
  • Adjust the strength slider per slot (how much the model can change the image)
  • Slot #1 is always the base image; slots #2+ are style references

Inpainting modes

Mode When to use
Crop & Composite (Fast) Quick edits — crops the masked region, generates at lower res, composites back
Inpainting Pipeline (Quality) Full-resolution inpainting — slower but cleaner results (Z-Image only)

Iterate Masks button

When Inpainting Pipeline (Quality) is selected and you have masks on multiple slots, the button changes to Iterate Masks. This chains the generation passes: output of pass N becomes the input of pass N+1, applying each mask in sequence.


Workflows

Workflows save your entire session — model, all parameters, reference images, masks, and strength values — into a folder under workflows/.

  • Save — type a name and click Save → creates workflows/yy-mm-dd_name/
  • Load — pick from the dropdown (last 15 shown) and click Load
  • Open — click the folder icon to browse to any workflow folder in Finder

Output files

Images are saved to ~/Pictures/ultra-fast-image-gen/ by default (change in Settings). Each image gets a .json sidecar with the prompt, seed, model, and all parameters.

Filename format: YYYYMMDD_prompt-slug.png (collisions get _2, _3 suffix). When reference images or masks are present, a companion folder prompt-slug/ is created alongside the image containing params.json, ref_slot_N.png, and mask.png.


Settings

Open Settings (gear icon, top-right):

Setting Description
Output folder Where generated images are saved
HuggingFace token Required for gated models
Models See which models are cached, download, delete
Upscale models Manage upscaler weights
Model Sources Curated list of base models, LoRAs, and upscalers — open HF page or download; locally cached entries highlighted with a green border
Server log View and save the current session log

Benchmarks

FLUX.2-klein-4B (4-bit SDNQ) — 512×512, 20 steps

Hardware Time
M3 Max (36 GB) ~11 s
M2 Max (32 GB) ~15 s

Z-Image Turbo (Quantized) — 512×512, 4 steps

Hardware Time
M2 Max ~14 s
M1 Max ~23 s

Project structure

off-line-Image-gen-mac/
├── server.py              ← FastAPI backend + static file server (main entry point)
├── app.py                 ← Generation logic, model management (no Gradio)
├── pipeline.py            ← Async bridge: FastAPI ↔ generation thread (SSE)
├── generate.py            ← CLI for Z-Image Turbo only
├── Launch.command         ← 1-click Mac launcher (production + dev modes)
│
├── frontend/              ← React + Vite + TypeScript UI → builds to frontend/dist/
│   └── src/
│       ├── App.tsx            ← Root: SSE handler, ref-slot logic, iterate loop
│       ├── store.ts           ← useReducer global state
│       ├── api.ts             ← Typed fetch helpers
│       ├── types.ts           ← Shared TypeScript types
│       └── components/
│           ├── Sidebar.tsx        ← All generation params + accordions
│           ├── Canvas.tsx         ← Result image / video + progress overlay
│           ├── RefImagesRow.tsx   ← Reference image slots + mask editor
│           ├── Gallery.tsx        ← Recent outputs strip
│           ├── TopBar.tsx         ← Brand, model, device, VRAM status
│           ├── SettingsDrawer.tsx ← HF login, model list, storage, log
│           ├── MaskEditorModal.tsx← Rectangle mask drawing canvas
│           └── HelpTip.tsx        ← Inline ⓘ tooltips
│
├── core/
│   ├── depth_map.py       ← DA3 / DA2 depth estimation → 16-bit PNG
│   ├── lora_flux2.py      ← LoRA for FLUX.2-klein (PEFT)
│   ├── lora_zimage.py     ← LoRA for Z-Image (forward-patch)
│   ├── quantized_flux2.py ← 4-bit SDNQ + int8 quantization
│   └── workflow_utils.py  ← Workflow save/load, ComfyUI importer
│
├── models/                ← Downloaded model weights (gitignored)
├── lora_uploads/          ← User-uploaded LoRA files (gitignored)
├── upscale_models/        ← Upscaler weights (gitignored)
├── workflows/             ← Saved workflow folders
└── logs/                  ← Server logs (server.log + timestamped snapshots)

Contributing

All contributions are welcome — bug reports, feature ideas, new model support, UI improvements, docs.

  • Bug? → open an Issue
  • Idea? → start a Discussion
  • Question? → use Q&A Discussions
  • Code? → fork, branch, PR — please describe what you changed and why

Credits


License

See the individual model licenses for usage terms. Project source code is provided as-is for personal and research use.

About

Fully offline AI image generation for Mac Silicon (MPS). FLUX.2, Z-Image Turbo, LTX-Video — no cloud, no subscriptions.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages