Built in 2023, before later image models made this interaction feel instant and trivial. AnimePics was a consumer funnel that collected subject info, payment, and training photos, then used GPU-backed ML to create personalized portrait galleries.

People were already paying artists on marketplaces such as Etsy to turn personal photos into anime portraits. Stable Diffusion 1.5 created an opening to deliver that familiar outcome through software, while new personalization techniques made it possible to preserve a specific customer’s identity across many scenes.
The customer desire was visible before the product existed. The opportunity was to make fulfillment repeatable.
Recent open models made it possible to train identity and generate many new scenes from a small photo set.
My frontend, backend, and infrastructure experience let me build the consumer product and the GPU system together.
User selects package, themes, and subject traits needed by prompts.
Stripe checkout creates a durable paid order before expensive GPU work starts.
Browser validates faces and crops images to the model's expected 512x512 input.
Backend queues a training job and shows progress as an order, not a blocking request.
Gallery supports public/private viewing, trial unlocks, downloads, and bonus content.
A key product decision was not to promise instant results. With one GPU, a single personalized job could take more than an hour, and a queue of orders could push delivery into multiple hours. The user experience was built around that reality: pay, upload validated photos, leave, then come back from email when the gallery was ready.
The wait was not hidden. The product flow made long-running generation normal.
Identity training, model merges, and prompt batches made queueing and status part of fulfillment.
Payment, upload, and fulfillment emails brought users back to finish uploads or view completed galleries.
Input quality had an outsized effect on the final gallery. The browser rejected bad photos and produced model-ready crops before the backend committed scarce GPU time.
The frontend collected payment, subject traits, and validated photos. The web service persisted the order and handed a bounded job to the GPU worker. Postgres stored durable state, S3 stored image binaries, and Kafka connected the long-running stages.
Tailwind
Zustand
React Query
NextAuth + Stripe
face-api.js + smartcrop
Litestar
SQLAlchemy
Stripe webhooks
Redis authz
orders and users
theme selection
training photo keys
result photo keys
training jobs
result-save jobs
manual commits
Pydantic schema
training
inference
PyTorch merging
prompt batches
high-res correction
upscaling
The product trained identity once, then branched into selected styles.
The GPU server used my own DreamBooth implementation to train a personalized checkpoint from the uploaded photos. Custom PyTorch code then merged that identity checkpoint into each selected style model. Reusing the checkpoint avoided training once per style and saved substantial GPU time. GPU compute was by far the product's largest expense.




Software gives me a fast, mostly deterministic feedback loop. Model training does not. The hardest part of this project was ensuring good results. I made my own DreamBooth implementation. I also customized training for each customer: I selected class-specific regularization data based on the customer’s subject class and normalized epoch count against the number of uploaded photos to target approximately 1,700 total training steps. I built prompt templates around characteristics such as hair, eyes, and age. I tested sampler settings and seeds, spent weeks curating better training sets, and added an upscaler step when customers paid for larger outputs. A major breakthrough was model merging. Instead of training each customer in four different styles, each with a different base model, I trained the identity once and transferred its learned delta into each style checkpoint. Model merging was still novel then, but it cut GPU time in half on average while preserving quality in the final outputs.
Just as gradient descent only tells you directionally where to go, improving the model felt similar. Each change had to be tested in isolation and run against multiple types of users.
The exact package versions had to line up with the GPU before training could run. Changing hardware often meant rebuilding the environment.
Great training data and an okay model > okay training data and a great model.
Train identity once, then transfer its learned delta into each style checkpoint: style + 0.9 × (personalized − base). That replaced four separate training runs while preserving output quality.
The product was better than competitors at the time, but marketing was weak and there was no built-in distribution loop.
At low volume, dedicated GPU capacity sat underused while paid acquisition failed to create enough demand to amortize it.
The result took more than an hour and could include only one person. People often wanted anime photos with friends, family, or pets.