StyleGAN2 · Non-commercial

TURRRBO

A desktop application for generating images from StyleGAN2 latent space. Point it at a seed. Adjust truncation. Explore what the model learned. No cloud. No subscription. No internet required.

What is TURRRBO?

TURRRBO is a desktop tool for artists, designers, and image experimenters. It wraps StyleGAN2 — a generative neural network architecture developed by NVIDIA — in a native macOS application that is focused on exploration and iteration rather than photorealism.

The value of the app comes from its model catalog, its parameter controls, and its style route system — a set of named artistic presets that bend the model's output toward specific aesthetic behaviors without requiring you to understand the underlying math.

Non-commercial only. TURRRBO uses pretrained weights from NVIDIA. These weights are licensed for non-commercial research use only. Do not use this application for commercial purposes.

What makes it different?

What TURRRBO is

  • A latent space navigator
  • A model behavior explorer
  • An art tool for unexpected outputs
  • A local, offline application
  • A catalog of trained visual behaviors

What TURRRBO is not

  • A text-to-image system like Stable Diffusion
  • A photorealistic image generator
  • A cloud service
  • A commercial tool
  • A fine-tuning or training platform

Installation

TURRRBO ships as a self-contained macOS app. Everything — Python backend, model weights, and the UI — is bundled inside the .app.

System Requirements

ComponentRequirement
OSmacOS 12 Monterey or later
ChipApple Silicon (M1/M2/M3) recommended · Intel supported
RAM8 GB minimum · 16 GB recommended for 1024px models
Disk~3 GB for the full app with all models
GPUMPS (Apple GPU) used automatically · CPU fallback available

Install the App

Download the .app from the releases page. Drag it to your Applications folder. On first launch, macOS may show a security warning — right-click the app and choose Open to bypass Gatekeeper.

First launch is slow. The Python backend needs to unpack on first run. Expect 15–30 seconds before the interface becomes interactive. The status bar at the bottom will show "starting backend…" while this happens.

Developer Setup (from source)

If you are building from source rather than using the bundled app, you need to set up the development environment:

bash
# 1. Clone StyleGAN2-ADA-PyTorch into vendor/
git clone https://github.com/NVlabs/stylegan2-ada-pytorch.git backend/vendor/stylegan2

# 2. Create Python virtual environment
python3 -m venv backend/.venv

# 3. Install dependencies
backend/.venv/bin/pip install torch torchvision fastapi uvicorn pydantic pillow numpy requests
backend/.venv/bin/pip install "numpy<2.0"  # required — StyleGAN2 uses numpy 1.x API
backend/.venv/bin/pip install git+https://github.com/openai/CLIP.git  # optional: for text prompts

# 4. Download model checkpoints
backend/.venv/bin/python3 scripts/download_models.py

# 5. Install Node dependencies
npm install
bash — run in dev mode
npm run tauri:dev

Available Models

The following pretrained checkpoints are downloaded by default:

IDNameResolutionSize
ffhq_1024Synthetic Portraits1024px329 MB
metfaces_1024Museum Wreckage1024px329 MB
lsun_churches_256Haunted Schematics256px403 MB
afhq_cats_512Animal Forms512px329 MB
lsun_cars_512Automotive Drift512px403 MB

Quick Start

Generate your first image in under a minute.

Generation workflow
1
Select a model
Choose from the left rail catalog. Each model was trained on a different dataset and produces a distinct visual character. Start with Synthetic Portraits (ffhq_1024).
left rail → Models
2
Set a seed
Each integer seed maps to a unique point in the model's latent space. Seed 0 and seed 1 produce completely different images. Use the randomize button (⟳) to explore.
right rail → Seed
3
Adjust truncation ψ
Low values (0.2–0.5) produce typical, safe-looking outputs. High values (0.8–1.4) push toward the model's extremes — more interesting, more unstable.
right rail → Truncation ψ
4
Generate
Click Generate or press ⌘ Enter. The image appears in the center panel. Generation takes 2–20 seconds depending on model resolution and your machine.
bottom of right rail → Generate
5
Export
Click Export PNG to save the full-resolution output. Open Folder opens the output directory in Finder.
center panel footer

How It Works

You are not describing an image. You are navigating a mathematical space that a neural network learned from a dataset of real images.

Latent Space

A StyleGAN2 model is trained to compress a dataset of images into a high-dimensional mathematical space called latent space. Every point in this space corresponds to an image. The model learns a mapping from any point in this space back to a full-resolution image.

Latent space — each dot is a possible image
mean (ψ=0)
seed 42
seed 7
ψ=0 (average)
ψ=1.4 (extreme)

Seeds

A seed is an integer (0 to 2,147,483,647) that TURRRBO converts into a starting vector in latent space using a deterministic random number generator. The same seed always produces the same image with the same model and parameters. Different seeds are different locations in latent space — different images.

Truncation ψ (psi)

Truncation controls how far your seed's point is allowed to stray from the model's mean (the "average" of everything it learned). Think of it as a dial between safe and typical versus extreme and unusual.

ψ rangeBehavior
0.0 – 0.3Collapsed toward the mean. Everything looks very "typical" for the model.
0.4 – 0.7Balanced. Most commonly used range for coherent outputs.
0.8 – 1.0High diversity. Outputs become unusual and more interesting.
1.0 – 1.4Beyond the standard range. Structural breakdown, artifacts, alien geometry.

Generation Pipeline

From seed to image
Input
Seed + ψ
integer → Z vector
Mapping
Z → W Space
8-layer MLP
Synthesis
W → Image
Progressive layers
Output
PNG file
256 / 512 / 1024px

Models

Each model is a trained checkpoint that defines a visual territory. Selecting a different model is like switching instruments.

Bundled Models

Synthetic Portraits
ffhq_1024 · 1024px
DatasetFFHQ — 70,000 human face photographs
CharacterCoherent faces at mid-psi. Disintegrates into anatomy-horror at ψ > 1.0
Best forPortrait work, synthetic identity, face mutation
Rec. ψ0.7
portraitfacehigh-res
Museum Wreckage
metfaces_1024 · 1024px
DatasetMetFaces — portrait paintings from the Metropolitan Museum of Art
CharacterPainterly surfaces, visible brushwork, art-historical drift
Best forPainting aesthetics, historical portrait mutation
Rec. ψ0.65
paintingmuseumportrait
Haunted Schematics
lsun_churches_256 · 256px
DatasetLSUN Outdoor Churches — cathedral and church facades
CharacterSpires, arches and rooflines against sky. Lowest res in the set — sketch-like, abstract structural compositions. Impossible architecture at high ψ
Best forArchitectural and gothic structural forms, dreamlike buildings
Rec. ψ0.7
architecturegothicstructure
Animal Forms
afhq_cats_512 · 512px
DatasetAFHQ (Animal Faces-HQ) — cats subset
CharacterClose-up feline faces with detailed fur, eyes and markings. Centered-subject, so seed-to-seed interpolation stays smooth and legible
Best forCreature / animal exploration, texture-rich fur detail
Rec. ψ0.7
animalcattexture
Automotive Drift
lsun_cars_512 · 512px
DatasetLSUN Cars — vehicle bodies and silhouettes
CharacterCar bodies from varied angles, usually three-quarter views. Object (not face) distribution, so orientation and composition shift noticeably between seeds. Exaggerated concept-car forms at high ψ
Best forAutomotive and industrial-object forms, body shapes, reflections
Rec. ψ0.7
objectvehicleindustrial

Adding Custom Models

Any StyleGAN2 or StyleGAN2-ADA checkpoint can be added to TURRRBO. Create a folder inside backend/models/ with a model_card.json and the .pkl file:

backend/models/
your_model_name/
model_card.json ← required
your_checkpoint.pkl ← the model weights
model_card.json
{
  "id": "your_model_name",          // must match folder name
  "name": "Display Name",
  "description": "What this model produces.",
  "resolution": 512,               // 256, 512, or 1024
  "category": "face",               // groups models in left rail
  "provenance": "Source and license.",
  "checkpoint_file": "your_checkpoint.pkl",
  "recommended_psi": 0.7,
  "tags": ["portrait", "abstract"]
}
The backend scans the models directory on startup. After adding a new model, restart the app and it will appear in the catalog automatically. No code changes needed.

Category values

The category field groups models in the left rail. Built-in values: face, art, architecture, animal, object. You can use any string — it becomes a new group heading.

Parameters

Every parameter in the right rail controls a specific aspect of how the model generates an image. None of them require you to understand the math.

Core Parameters

ParameterTypeRangeWhat it controls
Seed integer 0 – 2,147,483,647 Selects a point in latent Z space. Each seed is a distinct identity.
Truncation ψ float 0.0 – 1.5 How far from the model mean to go. Low = safe/typical. High = extreme/unusual.
Noise Mode enum const / random / none How stochastic surface detail is generated. const is deterministic. random varies per-run.
Noise Strength float 0.0 – 3.0 Scales the stochastic noise layer. High values flood the surface with detail.

Split Truncation

StyleGAN2 generates images in layers — coarse layers (0–3) control large-scale structure like pose and shape, while fine layers (8+) control surface detail and color. Split truncation lets you use a different ψ for each group.

ParameterLayersControls
Coarse ψ0–3Pose, scale, overall structure
Fine ψ8+Surface texture, color, fine detail
A useful combination: set Coarse ψ low (0.3) for a stable, recognizable structure, and Fine ψ high (1.2) for chaotic surface detail. This gives you structured instability.

Style Mixing

Style mixing lets two seeds contribute to a single image. The primary seed provides the default identity. The mix seed donates its W-space values at the selected layers.

ParameterWhat it does
Mix SeedA second seed whose W values are borrowed at the selected layers
Mix LayersWhich layers to borrow. Use the preset buttons: coarse / mid / fine / all

Style Routes

Style routes are named parameter adjustments that shift your dials at generation time — without permanently changing what you've set. Think of them as artistic modes.

Routes modify at generation time. Your sliders stay where you set them. The route adds its adjustments on top when you hit Generate. The effective parameters (what was actually used) are shown in the meta bar below the image.

Available Routes

Ghost Contour
ψ +0.20 · noise → random
Thermal Hallucination
ψ +0.25 · noise → const
Overexposed Memory
ψ −0.30 · noise → const
Broken Chroma
ψ ±0 · noise → random
TV Wreckage
ψ +0.35 · noise → random
Cartoon Corrosion
ψ +0.20 · noise → none
Structure Transplant
mix layers 0–3
Fine Transplant
mix layers 8–12
None
no adjustment — raw params

How Routes Are Applied

python — style_routes.py
# Routes adjust params at generation time, not permanently
def apply_route(route_id, params):
    route = ROUTES_BY_ID[route_id]
    result = dict(params)

    # Shift truncation, clamp to valid range
    result["truncation_psi"] = clamp(
        params["truncation_psi"] + route["psi_offset"],
        0.0, 1.5
    )
    # Override noise mode if route specifies one
    if route["noise_mode_override"]:
        result["noise_mode"] = route["noise_mode_override"]

    return result

CLIP / Text Prompts

When you type in the Text Prompt field, TURRRBO switches to CLIP-guided generation. The latent vector is optimized over multiple steps to maximize similarity between the generated image and your text.

CLIP is optional and must be installed separately. Run: backend/.venv/bin/pip install git+https://github.com/openai/CLIP.git. Without it, the text field is still present but CLIP mode is unavailable.

How CLIP Guidance Works

CLIP-guided optimization loop
1
Encode text
Your prompt is converted to a feature vector by CLIP's text encoder (ViT-B/32).
"melting wax face" → 512-dim vector
2
Initialize Z from seed
The seed parameter creates a starting point in latent space. CLIP will optimize from this starting point.
3
Optimization loop
For each step: generate an image, encode it with CLIP's image encoder, compute the loss (negative cosine similarity with the text vector), backpropagate, update Z.
Steps: 10 – 300 · LR: 0.001 – 0.2
4
Final render
After all steps, the final optimized Z is used to generate the output image at full resolution.

CLIP Parameters

ParameterDefaultEffect
Steps80More steps = more influence from the prompt. Also slower. 50–100 is a good range.
LR (Learning Rate)0.05How aggressively the latent moves per step. High values move fast but overshoot.
CLIP guidance doesn't guarantee you'll see your prompt literally — it steers the latent toward regions CLIP associates with your words. Effective prompts describe visual qualities ("oil paint texture", "infrared color", "melting wax") rather than subjects ("a person").

UI Overview

TURRRBO is a three-panel desktop instrument. Everything has a fixed place.

TURRRBO
Models (left rail)
Synthetic Portraits
Museum Wreckage
Haunted Schematics
Animal Forms
Automotive Drift
Center · Image preview
Controls (right rail)
Truncation ψ0.70
Noise Strength1.00
GENERATE

Left Rail — Model Catalog

Lists all available model checkpoints grouped by category. Click any model to load it. The selected model is highlighted and its recommended truncation value is applied to the ψ slider automatically.

Center Panel — Preview

Displays the generated image. The meta bar below the image shows the effective parameters used (accounting for any style route adjustments). Clicking a thumbnail in the history strip at the bottom restores those parameters.

Right Rail — Controls

All generation parameters live here. From top to bottom: Text Prompt, Style Route, Templates, Seed, Truncation, Split Truncation, Noise Mode, Noise Strength, Mix Seed, Randomize All, Generate button.

Status Bar

The footer shows backend health, the active compute device (MPS / CUDA / CPU), and the currently loaded model. A pulsing dot means the backend is still starting.

Keyboard Shortcuts

All shortcuts use Cmd on macOS so they never conflict with text input in the prompt field.

Generate image with current parameters
R
Randomize seed
E
Export current image (opens save dialog)
Space bar is intentionally unbound. Since TURRRBO has a text prompt field, Space is reserved for typing. Use ⌘ Enter to generate.

History & Export

Every generated image is saved automatically and kept in the history strip. Nothing is lost unless you manually delete it.

History Strip

The row of thumbnails at the bottom of the center panel shows the last 50 generations in the current session. Clicking any thumbnail restores its exact parameters — seed, ψ, noise mode, mix seed, and style route — back to the right rail so you can generate from that state again.

Output Files

All generated images are written to:

path
~/turrrbo_outputs/

Each generation creates two files:

FileWhat it is
[run_id].pngFull resolution output
[run_id]_preview.png512px preview used in the UI
[run_id].jsonSession metadata (if a note was added)

Exporting

Click Export PNG in the center panel footer to open a save dialog and copy the full-resolution output to a location of your choice. The file in ~/turrrbo_outputs/ is always preserved — Export creates a copy.

Click Open Folder to reveal the output directory in Finder.

Custom Models

Any StyleGAN2 or StyleGAN2-ADA .pkl checkpoint can be added to TURRRBO. The model catalog is entirely driven by JSON files on disk.

model_card.json — Full Reference

json
{
  "id": "my_model",
  // Must match the folder name exactly.
  // Used as the internal identifier everywhere.

  "name": "Display Name",
  // Shown in the left rail catalog.

  "description": "What this produces and how it behaves.",
  // Shown in the catalog when the model is selected.

  "resolution": 512,
  // Output resolution in pixels. Must match the checkpoint.
  // Valid values: 256, 512, 1024.

  "category": "face",
  // Groups models in the catalog.
  // Built-in: face, art, architecture, animal, object.
  // Any string works — creates a new group.

  "provenance": "Source URL and license information.",
  // Required for any third-party checkpoint.
  // Shown in the license panel.

  "checkpoint_file": "my_checkpoint.pkl",
  // Filename of the .pkl file relative to this folder.

  "recommended_psi": 0.7,
  // The truncation value loaded when this model is selected.
  // 0.5–0.8 is typical. Adjust based on the model's behavior.

  "tags": ["portrait", "texture"]
  // Shown as small badges. Describe aesthetic character.
}

Bundling Into a Build

For development, dropping the folder in and restarting is all it takes. But a packaged build is different: the .pkl files in backend/models/ are not pulled into the app automatically — Tauri only bundles what lives in src-tauri/resources/models/. Stage them first:

bash
npm run stage:models    # then: npm run tauri:build
If a new model works in npm run tauri:dev but is missing from the built .app/.msi, you forgot stage:models. This is the #1 "where did my model go" cause.

Finding Compatible Checkpoints

A large catalog of community-trained StyleGAN2 checkpoints is available at:

url
https://github.com/justinpinkney/awesome-pretrained-stylegan2

Any checkpoint listed there can be added to TURRRBO. Download the .pkl, create a folder in backend/models/, write the model_card.json, and restart the app.

Check the license of each checkpoint before use. Community models may have different licensing terms. Document the provenance in the provenance field.

Style Mixing

Style mixing is a core StyleGAN2 technique. Two seeds contribute to one image — one seed provides structure, another provides surface.

Concept

StyleGAN2 generates images in sequential layers. The early layers (coarse, 0–3) control global properties like pose, scale, and basic structure. Later layers (fine, 8–14) control surface texture, color, and fine detail.

Style mixing replaces some layers of Seed A's W vector with the corresponding layers from Seed B. The result is an image with Seed A's coarse structure and Seed B's fine texture — or vice versa.

Layer Groups

GroupLayersControls
Coarse0–3Pose, global shape, camera angle
Mid4–7Anatomy, proportion, mid-scale structure
Fine8–13Surface texture, color, fine detail, skin

Using It

Set a primary seed (the Seed field). Enable mixing by entering a mix seed. Use the layer preset buttons (coarse / mid / fine / all) to choose which layers are borrowed from the mix seed. Generate.

The Structure Transplant style route automatically activates coarse layer mixing (layers 0–3) when a mix seed is set. The Fine Transplant route activates fine layers (8–13).

Templates

Templates are built-in starting points that demonstrate specific techniques. They load a complete parameter configuration with one click.

Templates never overwrite your text prompt. Applying a template loads parameters and a style route, but your text in the prompt field is always preserved.

Built-in Templates

NameWhat it demonstrates
Raw OutputDefault settings, no adjustments. Baseline for comparison.
Average CollapseVery low ψ (0.2). Shows what the model considers "most typical."
Full ChaosMaximum ψ (1.4) + random noise + TV Wreckage route. Maximum instability.
Structure SwapStyle mixing with coarse layers. Two seeds, one image.
Texture DonorStyle mixing with fine layers. Surface from one seed, structure from another.
Split TruncationLow coarse ψ, high fine ψ. Stable structure, chaotic surface.
Noise FloodHigh noise strength. Stochastic layer overwhelms deterministic structure.
GhostHigh ψ + Ghost Contour route. Forms dissolve toward outlines.

Backend API

TURRRBO's Python backend exposes a local HTTP API on port 47474. The Tauri shell proxies all UI interactions through Rust commands to this API. You can also call it directly for scripting.

The API is only accessible on 127.0.0.1:47474. It is not exposed to the network. Interactive docs are available at http://127.0.0.1:47474/docs when the backend is running.
GET /health Backend status + device info
response
{
  "healthy": true,
  "gpu_available": true,
  "device": "mps",
  "loaded_model": "ffhq_1024",
  "version": "0.2.0",
  "clip_available": true
}
POST /generate Generate an image
request body
{
  "model_id": "ffhq_1024",
  "params": {
    "seed": 42,
    "truncation_psi": 0.7,
    "noise_mode": "const",
    "mix_seed": null,
    "mix_layers": null,
    "noise_strength": 1.0,
    "coarse_psi": null,
    "fine_psi": null
  },
  "style_route": "none",
  "text_prompt": null,
  "clip_steps": 80,
  "clip_lr": 0.05
}
response
{
  "ok": true,
  "output_image": "/Users/.../turrrbo_outputs/2026-04-08T12-00-00Z_abc123.png",
  "preview_image": "/Users/.../turrrbo_outputs/2026-04-08T12-00-00Z_abc123_preview.png",
  "model_id": "ffhq_1024",
  "run_id": "2026-04-08T12-00-00Z_abc123",
  "timing_ms": 4821,
  "warnings": [],
  "effective_params": { /* actual params used after route adjustment */ },
  "clip_guided": false
}
GET /models List all available models
GET /style-routes List all style routes
GET /templates List built-in templates

Architecture

TURRRBO is a native desktop app with three layers: a Tauri shell (Rust), a React frontend, and a Python inference service.

System architecture
Frontend
React
TypeScript · Zustand · Vite
Shell
Tauri
Rust · Tauri v1
Backend
FastAPI
Python · port 47474
Inference
StyleGAN2
PyTorch · MPS / CUDA

Communication Flow

The React UI never talks to the Python backend directly. All communication goes through Tauri commands — Rust functions that the frontend calls via invoke(). The Rust layer then makes HTTP requests to the Python sidecar on localhost.

typescript → rust → python
// Frontend calls a Tauri command
const result = await invoke("generate_image", { request })

// Rust proxies to Python backend
// src-tauri/src/commands.rs
client().post("http://127.0.0.1:47474/generate")
        .json(&request)
        .send().await

// Python handles inference
# backend/api/server.py
engine.generate(seed, truncation_psi, ...)

Project Structure

turrrbo/
src/ ← React frontend
App.tsx
components/ ModelCatalog · ParameterControls · PreviewPanel · StatusBar
store/ generatorStore.ts — Zustand global state
src-tauri/ ← Rust / Tauri shell
src/
commands.rs ← all Tauri ↔ Python command handlers
main.rs ← app entry, sidecar launch
sidecar.rs ← Python backend launch + health poll
backend/ ← Python inference service
api/server.py ← FastAPI server (port 47474)
stylegan_engine/
inference.py ← StyleGAN2 wrapper
model_registry.py ← scans models/ for model_card.json
style_routes.py ← route definitions + apply_route()
templates.py ← built-in parameter templates
models/ ← one subfolder per checkpoint
vendor/stylegan2/ ← cloned from NVlabs (not committed)

Building & Distribution

Building TURRRBO for distribution produces a self-contained app — a macOS .app/.dmg or a Windows .msi/.exe. No Python installation required on the end user's machine.

Prerequisites

You need all developer dependencies installed: Rust, Node.js, Python 3.10–3.13 (not 3.14), and PyInstaller.

bash
backend/.venv/bin/pip install pyinstaller

Build Steps

A distribution build is three steps: stage the model weights, freeze the Python backend into a sidecar binary, then let Tauri bundle everything.

Step 0 — stage the models, or you ship zero of them. The .pkl weights live in backend/models/, but Tauri only packages what's in src-tauri/resources/models/. Staging copies them across. Run this before every build that added or changed a model.
bash — step 0: stage models
npm run stage:models   # runs scripts/stage_models.js (cross-platform)
bash — step 1 (macOS): build Python sidecar
backend/.venv/bin/python3 -m PyInstaller \
    --clean --noconfirm \
    --distpath "src-tauri/binaries/_dist" \
    --workpath "build/pyinstaller" \
    backend/turrrbo_backend.spec

cp src-tauri/binaries/_dist/turrrbo-backend \
   src-tauri/binaries/turrrbo-backend-aarch64-apple-darwin
chmod +x src-tauri/binaries/turrrbo-backend-aarch64-apple-darwin
cmd — step 1 (Windows): build Python sidecar
backend\.venv\Scripts\python -m PyInstaller ^
    --clean --noconfirm ^
    --distpath "src-tauri\binaries\_dist" ^
    --workpath "build\pyinstaller" ^
    backend\turrrbo_backend.spec

copy src-tauri\binaries\_dist\turrrbo-backend.exe ^
     src-tauri\binaries\turrrbo-backend-x86_64-pc-windows-msvc.exe
The sidecar binary must be renamed to include the target triple (-aarch64-apple-darwin, -x86_64-pc-windows-msvc). Tauri resolves the sidecar by appending the platform triple to the base name in externalBin; a mismatch is a hard build failure.
bash — step 2: build the app
npm run tauri:build

Output Locations

PlatformArtifact
macOSsrc-tauri/target/release/bundle/macos/TURRRBO.app (and .dmg)
Windows · MSIsrc-tauri/target/release/bundle/msi/TURRRBO_0.1.0_x64_en-US.msi
Windows · NSISsrc-tauri/target/release/bundle/nsis/TURRRBO_0.1.0_x64-setup.exe

Build Order

pipeline
download_models.py  →  stage:models  →  PyInstaller (sidecar)  →  tauri:build
   (one-time)           (after a model    (when backend code         (produces
                         changes)          or deps change)            installer)

For a routine release with no backend or model changes, the sidecar from a previous build can be reused — only re-run PyInstaller when the Python code or its dependencies changed.

Python version matters. PyInstaller has known issues with Python 3.14. Use Python 3.10–3.13 for building the sidecar. The venv python version is what matters, not your system python.

Development Mode

In development, the Python backend is launched by concurrently alongside Tauri. No sidecar binary is needed.

bash
npm run tauri:dev

To iterate on the backend alone (faster restart loop), run it standalone and point Tauri at :47474:

bash
# macOS / Linux
backend/.venv/bin/python3 backend/api/server.py --port 47474

# Windows
backend\.venv\Scripts\python backend\api\server.py --port 47474
Cross-platform path gotcha. The backend script in package.json hard-codes a venv path: backend/.venv/bin/python3 on macOS, backend\.venv\Scripts\python on Windows. When moving the checkout between platforms, update that one script.

Troubleshooting

Build and launch failures we've actually hit, with the fix. Ordered roughly by how often they come up — search by the symptom.

ModuleNotFoundError: No module named 'torch'

symptom
File ".../backend/api/server.py", line 19, in <module>
    import torch
ModuleNotFoundError: No module named 'torch'

Cause. PyTorch is intentionally left out of requirements.txt (the correct wheel is platform-specific), so a fresh venv has no torch — or you launched with a different Python than the venv that has it.

Fix. Install the right variant into backend/.venv and launch with that interpreter:

bash
# Apple Silicon
backend/.venv/bin/pip install torch torchvision
# CUDA 12.1
backend/.venv/bin/pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121
# CPU
backend/.venv/bin/pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu

Sidecar binary not found / Tauri refuses to compile

Symptom. npm run tauri:build (or dev) fails immediately, before any code compiles, complaining about a missing binary referenced in externalBin.

Cause. Tauri validates that every externalBin entry physically exists at build time. If PyInstaller hasn't run yet, or the binary isn't renamed with the correct target triple, the expected file isn't there.

Fix (distribution build). Build the sidecar first and rename it to include the target triple:

expected paths
src-tauri/binaries/turrrbo-backend-aarch64-apple-darwin       # macOS Apple Silicon
src-tauri/binaries/turrrbo-backend-x86_64-pc-windows-msvc.exe # Windows x64

Fix (dev only). You don't need a sidecar in dev. Remove the externalBin key from src-tauri/tauri.conf.json and run the Python backend via npm run tauri:dev (or manually). Re-add externalBin only when packaging.

New model missing from the built app

Symptom. A model shows up in npm run tauri:dev but is absent from the packaged .app / .msi / .exe.

Cause. The .pkl was never staged into src-tauri/resources/models/. Tauri only bundles what's under resources/, not what's in backend/models/.

bash
npm run stage:models
npm run tauri:build

PyInstaller fails / sidecar crashes on launch

Symptom. PyInstaller errors during the freeze, or the bundled binary exits immediately at runtime.

Cause: Python 3.14. It has known incompatibilities with PyInstaller. Use Python 3.10–3.13 for the venv that builds the sidecar. The venv's Python version is what matters, not the system Python. Recreate the venv on a supported version and reinstall deps if needed.

Model fails to resolve / not appearing in the catalog

Check these, in order:

  • id in model_card.json doesn't match the folder name → make them identical.
  • checkpoint_file is a path instead of a bare filename → it must be just the filename, relative to the model's own folder.
  • resolution doesn't match the actual checkpoint → inference errors on first generate; correct the card to the checkpoint's native resolution.
  • Backend wasn't restarted → the registry only scans on startup.

Cross-platform breakage (macOS ↔ Windows)

  • The backend script in package.json uses a per-OS venv path — backend/.venv/bin/python3 (macOS) vs backend\.venv\Scripts\python (Windows). Update it for the current platform.
  • The sidecar binary needs a .exe extension on Windows; the rename step and sidecar.rs handle this per platform.
  • Use npm run stage:models (Node-based stage_models.js) rather than any bash loop — the Node script is the cross-platform staging path.

Quick triage checklist

1. Does backend/.venv have torch? (backend/.venv/bin/python -c "import torch")
2. Is the venv Python 3.10–3.13?
3. Did you npm run stage:models before tauri:build?
4. For a distribution build, does the sidecar binary exist with the correct target-triple suffix?
5. For each model: id == folder name, checkpoint_file is a bare filename, resolution matches the checkpoint.

License & Attribution

TURRRBO depends on components with specific licensing requirements. Understanding these is important before distributing or using the application.

Non-commercial use only. The pretrained StyleGAN2 model weights are covered by NVIDIA's non-commercial research license. This application may not be used for commercial purposes.

NVIDIA StyleGAN2 Weights

The pretrained checkpoints (FFHQ, MetFaces, LSUN, AFHQ) are property of NVIDIA Corporation, licensed for non-commercial research use only.

license
Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
Non-commercial research use only.
https://nvlabs.github.io/stylegan2/license.html

StyleGAN2-ADA-PyTorch

The inference code from the NVlabs repository is used under the same NVIDIA non-commercial license.

PyTorch

PyTorch is used under the BSD-style license. Full text: https://github.com/pytorch/pytorch/blob/main/LICENSE

Tauri

The Tauri framework is used under the MIT / Apache-2.0 dual license.

CLIP

OpenAI CLIP is used under the MIT license when installed. It is an optional dependency.

Attribution Requirements

Any redistribution of TURRRBO must include:

resources/licenses/THIRD_PARTY_LICENSES.txt

This file is bundled inside the app at Contents/Resources/resources/licenses/.