commit 72f40c77925d1ddbcdfc07619ddc85ab70b3bc00 Author: Daniel Date: Sun Sep 27 15:20:26 2026 -0500 Initial commit diff --git a/.directory b/.directory new file mode 100644 index 0000000..d69f7a9 --- /dev/null +++ b/.directory @@ -0,0 +1,2 @@ +[Desktop Entry] +Icon=folder-green diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..824066a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,25 @@ +# Uses the exact same verified environment as your Dev Container +FROM nvcr.io/nvidia/pytorch:25.02-py3 + +# Install API and Flux-specific dependencies +# Note: We skip the torch versions in your list because the NVIDIA base +# already includes the optimized sm_120 version we need. +RUN pip3 install --no-cache-dir \ + fastapi \ + uvicorn \ + pydantic \ + transformers==4.46.1 \ + diffusers==0.35.2 \ + accelerate==0.30.1 \ + sentencepiece \ + protobuf + +# Set up the application +WORKDIR /app +COPY api.py /app/api.py + +# Ensure GPU visibility (matching your devcontainer.json) +ENV NVIDIA_VISIBLE_DEVICES=all +ENV NVIDIA_DRIVER_CAPABILITIES=compute,utility + +CMD ["python3", "api.py"] diff --git a/api.py b/api.py new file mode 100644 index 0000000..c6f0935 --- /dev/null +++ b/api.py @@ -0,0 +1,57 @@ +import os +import base64 +from io import BytesIO +from fastapi import FastAPI, HTTPException +from fastapi.middleware.cors import CORSMiddleware +from pydantic import BaseModel +import torch +from diffusers import FluxPipeline + +app = FastAPI() + +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + +print("Initializing Flux-Schnell on RTX 5060 Ti (sm_120)...") +hf_token = os.environ.get("HF_TOKEN") + +pipe = FluxPipeline.from_pretrained( + "black-forest-labs/FLUX.1-schnell", + torch_dtype=torch.bfloat16, + token=hf_token +) + +# Offload execution stages sequentially to maintain 16GB headroom +pipe.enable_sequential_cpu_offload() +pipe.vae.enable_tiling() + +class ImageRequest(BaseModel): + prompt: str + model: str = "flux-schnell" + +@app.post("/v1/images/generations") +async def generate(request: ImageRequest): + try: + result = pipe( + request.prompt, + guidance_scale=0.0, + num_inference_steps=4, + max_sequence_length=256, + ).images[0] + + buffered = BytesIO() + result.save(buffered, format="PNG") + img_str = base64.b64encode(buffered.getvalue()).decode() + + return {"data": [{"b64_json": img_str}]} + except Exception as e: + raise HTTPException(status_code=500, detail=str(e)) + +if __name__ == "__main__": + import uvicorn + uvicorn.run(app, host="0.0.0.0", port=5005) diff --git a/api_bk1.py b/api_bk1.py new file mode 100644 index 0000000..04e0d50 --- /dev/null +++ b/api_bk1.py @@ -0,0 +1,59 @@ +from fastapi import FastAPI, HTTPException +from fastapi.middleware.cors import CORSMiddleware +from pydantic import BaseModel +import torch +from diffusers import FluxPipeline +import base64 +from io import BytesIO + +app = FastAPI() + +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + +# Load FLUX.1-schnell (Best for 16GB VRAM + Fast Generation) +print("Initializing Flux-Schnell on RTX 5060 Ti (sm_120)...") +try: + pipe = FluxPipeline.from_pretrained( + "black-forest-labs/FLUX.1-schnell", + torch_dtype=torch.bfloat16 + ) + # Optimized for 16GB: Moves parts of the model to CPU when not in use + # pipe.enable_model_cpu_offload() + pipe.enable_sequential_cpu_offload() + pipe.vae.enable_tiling() +except Exception as e: + print(f"Error loading model: {e}") + +class ImageRequest(BaseModel): + prompt: str + model: str = "flux-schnell" # Matches the error fix from earlier + +@app.post("/v1/images/generations") +async def generate(request: ImageRequest): + try: + # Flux-Schnell generates high quality in just 4 steps + result = pipe( + request.prompt, + guidance_scale=0.0, + num_inference_steps=4, + max_sequence_length=256, + ).images[0] + + # Convert to Base64 for the API response + buffered = BytesIO() + result.save(buffered, format="PNG") + img_str = base64.b64encode(buffered.getvalue()).decode() + + return {"data": [{"b64_json": img_str}]} + except Exception as e: + raise HTTPException(status_code=500, detail=str(e)) + +if __name__ == "__main__": + import uvicorn + uvicorn.run(app, host="0.0.0.0", port=5005) diff --git a/create-image-skill b/create-image-skill new file mode 100755 index 0000000..6018126 --- /dev/null +++ b/create-image-skill @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +set -e + +PROMPT="$1" +SERVER_IP="192.168.2.154" +API_URL="http://${SERVER_IP}:5005/v1/images/generations" + +# Note: Using "flux-schnell" to match our api.py logic +RESPONSE=$(curl -s -X POST "$API_URL" \ + -H "Content-Type: application/json" \ + -d "{ + \"prompt\": \"$PROMPT\", + \"model\": \"flux-schnell\" + }") + +BASE64=$(echo "$RESPONSE" | jq -r '.data[0].b64_json') + +if [ "$BASE64" == "null" ]; then + echo "Error: $(echo "$RESPONSE" | jq -r .detail)" + exit 1 +fi + +OUTDIR="downloads/flux_images" +mkdir -p "$OUTDIR" +OUTFILE="${OUTDIR}/$(date +%s).png" + +echo "$BASE64" | base64 -d > "$OUTFILE" +echo "Image generated: $OUTFILE" diff --git a/downloads/flux_images/1776434378.png b/downloads/flux_images/1776434378.png new file mode 100644 index 0000000..17a3915 Binary files /dev/null and b/downloads/flux_images/1776434378.png differ diff --git a/downloads/flux_images/aidan at work.png b/downloads/flux_images/aidan at work.png new file mode 100644 index 0000000..aa39d7e Binary files /dev/null and b/downloads/flux_images/aidan at work.png differ diff --git a/downloads/flux_images/congrats helena v1.png b/downloads/flux_images/congrats helena v1.png new file mode 100644 index 0000000..5bc0767 Binary files /dev/null and b/downloads/flux_images/congrats helena v1.png differ diff --git a/downloads/flux_images/helena empty.png b/downloads/flux_images/helena empty.png new file mode 100644 index 0000000..2238640 Binary files /dev/null and b/downloads/flux_images/helena empty.png differ diff --git a/downloads/flux_images/hulk on island.png b/downloads/flux_images/hulk on island.png new file mode 100644 index 0000000..c64a7e0 Binary files /dev/null and b/downloads/flux_images/hulk on island.png differ diff --git a/downloads/flux_images/lois punches superman.png b/downloads/flux_images/lois punches superman.png new file mode 100644 index 0000000..79f2ba2 Binary files /dev/null and b/downloads/flux_images/lois punches superman.png differ diff --git a/downloads/flux_images/olive smoking.png b/downloads/flux_images/olive smoking.png new file mode 100644 index 0000000..84988fa Binary files /dev/null and b/downloads/flux_images/olive smoking.png differ diff --git a/downloads/flux_images/trees lake mountain.png b/downloads/flux_images/trees lake mountain.png new file mode 100644 index 0000000..e7f2c12 Binary files /dev/null and b/downloads/flux_images/trees lake mountain.png differ diff --git a/flux-index.html b/flux-index.html new file mode 100644 index 0000000..d67856b --- /dev/null +++ b/flux-index.html @@ -0,0 +1,295 @@ + + + + + + Flux Image Generator + + + +

Flux Image Generator

+

Powered by flux-schnell

+ +
+ + +
+ +
+ + +
+ +

+ +
+ +
+ + + +