Complete Guide to ComfyUI on Mac - Installation, Configuration, and Troubleshooting

ComfyUI might be exactly what you need. Unlike other Stable Diffusion interfaces, ComfyUI offers a node-based approach that gives you unprecedented control over the image generation process. In this comprehensive guide, I'll walk you through setting up ComfyUI on Apple Silicon Macs (M1, M2, M3), from installation to advanced configuration and troubleshooting.
What is ComfyUI?
ComfyUI is an open-source, node-based interface for Stable Diffusion that allows you to create complex AI image generation workflows visually. Think of it as a visual programming environment specifically designed for AI image generation. Instead of typing commands, you connect nodes (components) together to build your desired pipeline.
Key advantages of ComfyUI include:
- Highly modular and customizable workflows
- Memory-efficient processing (works even on GPUs with 1GB VRAM)
- Support for numerous models and extensions
- Fast startup and asynchronous queue system
- Smart re-execution (only recalculates changed nodes)
One-Shot Installation Script
If you prefer a hassle-free installation, you can use this one-shot installer script that handles everything automatically. This script will install Miniconda, set up a Python environment, clone ComfyUI, and download models.
#!/bin/bash
# ComfyUI One-Shot Installer for Mac with Apple Silicon
# This script installs Miniconda, sets up a Python environment,
# downloads ComfyUI, and installs all necessary dependencies and models.
# Set up colors for output
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color
# Functions to print colored messages
info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Function to check if command exists
command_exists() {
command -v "$1" >/dev/null 2>&1
}
# Check if running on macOS
if [[ "$(uname)" != "Darwin" ]]; then
error "This script is intended for macOS only."
exit 1
fi
# Check if running on Apple Silicon
if [[ "$(uname -m)" != "arm64" ]]; then
warning "This script is optimized for Apple Silicon Macs (M1/M2/M3). You appear to be using an Intel Mac."
read -p "Continue anyway? (y/n): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
fi
# Display warning about disk space and download size
echo "=========================================================="
echo " ComfyUI One-Shot Installer for Mac"
echo "=========================================================="
echo
warning "This script will:"
echo " 1. Install Miniconda if not already installed"
echo " 2. Create a Python environment for ComfyUI"
echo " 3. Clone the ComfyUI repository to ~/Documents/GitHub/ComfyUI"
echo " 4. Install required dependencies"
echo " 5. Download SD models, VAE models, and ControlNet models"
echo
warning "You'll need approximately:"
echo " - 3GB for Miniconda and the Python environment"
echo " - 2GB for ComfyUI and dependencies"
echo " - 10GB+ for models (SD 1.5, SDXL, VAEs, ControlNet models, etc.)"
echo " - Total: At least 15GB of free disk space"
echo
warning "The download may take a significant amount of time depending on your internet connection."
echo
read -p "Do you want to continue? (y/n): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
info "Installation cancelled."
exit 0
fi
# Set up paths - Using the standard GitHub directory
GITHUB_DIR="$HOME/Documents/GitHub"
COMFYUI_DIR="$GITHUB_DIR/ComfyUI"
MINICONDA_DIR="$HOME/miniconda3"
MINICONDA_INSTALLER="/tmp/miniconda.sh"
ENV_NAME="comfyui"
# Create GitHub directory if it doesn't exist
info "Setting up directories..."
mkdir -p "$GITHUB_DIR"
success "GitHub directory ready at $GITHUB_DIR"
# Check for Conda installation
if ! command_exists conda; then
info "Conda not found. Installing Miniconda..."
# Download Miniconda installer
info "Downloading Miniconda installer..."
curl -L -o "$MINICONDA_INSTALLER" "https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-arm64.sh"
# Run the installer
bash "$MINICONDA_INSTALLER" -b -p "$MINICONDA_DIR"
# Initialize conda
"$MINICONDA_DIR/bin/conda" init "$(basename "$SHELL")"
# Make conda available in this script
source "$MINICONDA_DIR/etc/profile.d/conda.sh"
success "Miniconda installed."
else
info "Conda already installed, continuing with existing installation."
# Make conda available in this script
if [[ -f "$MINICONDA_DIR/etc/profile.d/conda.sh" ]]; then
source "$MINICONDA_DIR/etc/profile.d/conda.sh"
elif [[ -f "$HOME/anaconda3/etc/profile.d/conda.sh" ]]; then
source "$HOME/anaconda3/etc/profile.d/conda.sh"
else
# Try to find conda.sh in other common locations
CONDA_PATH=$(which conda)
CONDA_BASE=$(dirname $(dirname "$CONDA_PATH"))
if [[ -f "$CONDA_BASE/etc/profile.d/conda.sh" ]]; then
source "$CONDA_BASE/etc/profile.d/conda.sh"
else
error "Could not find conda.sh. Please run 'conda init bash' (or your shell) and restart this script."
exit 1
fi
fi
fi
# Check for existing environment and create if needed
info "Checking for existing ComfyUI environment..."
if conda env list | grep -q "^$ENV_NAME "; then
warning "Environment '$ENV_NAME' already exists."
read -p "Do you want to recreate it? All packages in this environment will be lost. (y/n): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
conda env remove -n "$ENV_NAME" -y
conda create -n "$ENV_NAME" python=3.11 -y
success "Environment recreated."
else
info "Using existing environment."
fi
else
info "Creating new environment with Python 3.11..."
conda create -n "$ENV_NAME" python=3.11 -y
success "Environment created."
fi
# Activate the environment
info "Activating ComfyUI environment..."
conda activate "$ENV_NAME"
# Check if activation worked
if [[ "$CONDA_DEFAULT_ENV" != "$ENV_NAME" ]]; then
error "Failed to activate Conda environment. Please run this script again."
exit 1
fi
# Clone ComfyUI repository
info "Checking for existing ComfyUI installation..."
if [ -d "$COMFYUI_DIR" ]; then
warning "ComfyUI directory already exists at $COMFYUI_DIR."
read -p "Do you want to update it? (y/n): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
cd "$COMFYUI_DIR"
git pull
success "ComfyUI updated."
else
info "Keeping existing ComfyUI installation."
fi
else
info "Cloning ComfyUI repository to $COMFYUI_DIR..."
git clone https://github.com/comfyanonymous/ComfyUI.git "$COMFYUI_DIR"
success "ComfyUI cloned."
fi
# Navigate to ComfyUI directory
cd "$COMFYUI_DIR"
# Install PyTorch
info "Installing PyTorch for Apple Silicon..."
pip install --pre torch torchvision torchaudio --index-url https://download.pytorch.org/whl/nightly/cpu
# Install dependencies
info "Installing ComfyUI dependencies..."
pip install -r requirements.txt
pip install safetensors einops
# Create configuration file
info "Setting up configuration file..."
cat > extra_model_paths.yaml << EOL
# ComfyUI extra model paths configuration
# This file helps ComfyUI find and map your models
# Main ComfyUI installation
comfyui:
base_path: $COMFYUI_DIR/
is_default: true
checkpoints: models/checkpoints/
clip: models/clip/
clip_vision: models/clip_vision/
configs: models/configs/
controlnet: models/controlnet/
diffusion_models: models/diffusion_models/
embeddings: models/embeddings/
loras: models/loras/
upscale_models: models/upscale_models/
vae: models/vae/
vae_approx: models/vae_approx/
# Model aliases to automatically map model filenames
# When ComfyUI looks for a file on the left, it will use the file on the right instead
checkpoint_aliases:
# SD 1.5 aliases
v1-5-pruned-emaonly-fp16.safetensors: sd_v1-5.safetensors
v1-5-pruned-emaonly.safetensors: sd_v1-5.safetensors
v1-5-pruned.safetensors: sd_v1-5.safetensors
v1-5.safetensors: sd_v1-5.safetensors
# SDXL aliases
sd_xl_base_1.0.safetensors: sdxl_base_1.0.safetensors
sdxl-base-1.0.safetensors: sdxl_base_1.0.safetensors
# VAE aliases
vae-ft-mse-840000-ema-pruned.safetensors: sd_vae.safetensors
sdxl_vae.safetensors: sdxl_vae.safetensors
EOL
success "Configuration file created."
# Create model directories
info "Creating model directories..."
mkdir -p models/checkpoints
mkdir -p models/vae
mkdir -p models/lora
mkdir -p models/controlnet
mkdir -p models/embeddings
mkdir -p models/vae_approx
mkdir -p models/clip
success "Model directories created."
# Ask about downloading models
echo
warning "Model files are large (10GB+). Do you want to download them now?"
echo "1: Download all models (SD 1.5, SDXL, VAEs, preview models, ControlNet) [10GB+]"
echo "2: Download minimal set (SD 1.5, VAE, preview models) [2GB]"
echo "3: Skip model download (you'll need to add models manually later)"
echo
read -p "Enter your choice (1-3): " model_choice
if [[ "$model_choice" == "1" ]]; then
# Download all models
info "Downloading all models (this will take some time)..."
info "Downloading SD 1.5 models..."
curl -L --progress-bar "https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/v1-5-pruned-emaonly.safetensors" -o "models/checkpoints/sd_v1-5.safetensors"
info "Downloading SDXL model..."
curl -L --progress-bar "https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/resolve/main/sd_xl_base_1.0.safetensors" -o "models/checkpoints/sdxl_base_1.0.safetensors"
info "Downloading VAE models..."
curl -L --progress-bar "https://huggingface.co/stabilityai/sd-vae-ft-mse-original/resolve/main/vae-ft-mse-840000-ema-pruned.safetensors" -o "models/vae/sd_vae.safetensors"
curl -L --progress-bar "https://huggingface.co/madebyollin/sdxl-vae-fp16-fix/resolve/main/sdxl_vae.safetensors" -o "models/vae/sdxl_vae.safetensors"
info "Downloading preview models..."
curl -L --progress-bar "https://github.com/madebyollin/taesd/raw/main/taesd_decoder.pth" -o "models/vae_approx/taesd_decoder.pth"
curl -L --progress-bar "https://github.com/madebyollin/taesd/raw/main/taesdxl_decoder.pth" -o "models/vae_approx/taesdxl_decoder.pth"
curl -L --progress-bar "https://huggingface.co/comfyanonymous/taesd/resolve/main/taesd3_decoder.pth" -o "models/vae_approx/taesd3_decoder.pth"
curl -L --progress-bar "https://huggingface.co/comfyanonymous/taesd/resolve/main/taef1_decoder.pth" -o "models/vae_approx/taef1_decoder.pth"
info "Downloading ControlNet models..."
curl -L --progress-bar "https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_canny.pth" -o "models/controlnet/control_v11p_sd15_canny.pth"
curl -L --progress-bar "https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_openpose.pth" -o "models/controlnet/control_v11p_sd15_openpose.pth"
# After downloading models, create symbolic links for maximum compatibility
info "Creating symbolic links for model compatibility..."
cd models/checkpoints
ln -s sd_v1-5.safetensors v1-5-pruned-emaonly-fp16.safetensors
ln -s sd_v1-5.safetensors v1-5-pruned-emaonly.safetensors
ln -s sd_v1-5.safetensors v1-5-pruned.safetensors
ln -s sd_v1-5.safetensors v1-5.safetensors
ln -s sdxl_base_1.0.safetensors sd_xl_base_1.0.safetensors
ln -s sdxl_base_1.0.safetensors sdxl-base-1.0.safetensors
cd ../..
success "Symbolic links created for maximum compatibility."
elif [[ "$model_choice" == "2" ]]; then
# Download minimal set
info "Downloading minimal model set..."
info "Downloading SD 1.5 models..."
curl -L --progress-bar "https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/v1-5-pruned-emaonly.safetensors" -o "models/checkpoints/sd_v1-5.safetensors"
info "Downloading VAE model..."
curl -L --progress-bar "https://huggingface.co/stabilityai/sd-vae-ft-mse-original/resolve/main/vae-ft-mse-840000-ema-pruned.safetensors" -o "models/vae/sd_vae.safetensors"
info "Downloading preview models..."
curl -L --progress-bar "https://github.com/madebyollin/taesd/raw/main/taesd_decoder.pth" -o "models/vae_approx/taesd_decoder.pth"
curl -L --progress-bar "https://github.com/madebyollin/taesd/raw/main/taesdxl_decoder.pth" -o "models/vae_approx/taesdxl_decoder.pth"
# After downloading models, create symbolic links for maximum compatibility
info "Creating symbolic links for model compatibility..."
cd models/checkpoints
ln -s sd_v1-5.safetensors v1-5-pruned-emaonly-fp16.safetensors
ln -s sd_v1-5.safetensors v1-5-pruned-emaonly.safetensors
ln -s sd_v1-5.safetensors v1-5-pruned.safetensors
ln -s sd_v1-5.safetensors v1-5.safetensors
cd ../..
success "Symbolic links created for maximum compatibility."
else
info "Skipping model download. You'll need to add models manually later."
fi
# Create launcher script
info "Creating launcher script..."
cat > "$HOME/start_comfyui.sh" << EOL
#!/bin/bash
# ComfyUI Launcher Script
# Activate the Conda environment
source "\$(conda info --base)/etc/profile.d/conda.sh"
conda activate $ENV_NAME
# Navigate to ComfyUI directory
cd $COMFYUI_DIR
# Start ComfyUI with high-quality previews
python main.py --preview-method taesd
EOL
chmod +x "$HOME/start_comfyui.sh"
success "Launcher script created at ~/start_comfyui.sh"
# Installation complete
echo
echo "=========================================================="
echo " ComfyUI Installation Complete!"
echo "=========================================================="
echo
success "ComfyUI has been installed successfully!"
echo
info "To start ComfyUI, run:"
echo " ~/start_comfyui.sh"
echo
info "When ComfyUI is running, access it by opening:"
echo " http://127.0.0.1:8188 in your web browser"
echo
info "Installation details:"
echo " - ComfyUI directory: $COMFYUI_DIR"
echo " - Conda environment: $ENV_NAME"
echo " - Models directory: $COMFYUI_DIR/models"
echo
warning "Remember to run 'conda activate $ENV_NAME' before using ComfyUI if you don't use the launcher script."
echo
success "Happy generating!"
Echo
Save this script to a file (e.g., install_comfyui.sh
), make it executable with
chmod +x install_comfyui.sh,
and run it with
./install_comfyui.sh
.
Open your web browser and navigate to http://127.0.0.1:8188 to access the ComfyUI interface.
Other Articles