@levelsio created AvatarAI.me in November that creates AI generated avatars based on photos of you. You can create profile pictures, pet portraits, professional LinkedIn photos and much more!
This comes off the back of a machine learning model called Dreambooth which is a fine-tuned text-to-image diffusion model for subject driven generation. This means Dreambooth can generate images based on a subject such as a person, a dog or a fictional character. From initial release, AvatarAI.me quickly caught traction generating in excess of $200k in just 1 month! @Levelsio does have 200k followers which did make distribution slightly easier but it is still impressive nonetheless.
Due to its traction we thought we would recreate a version of AvatarAI using our simple model deployment framework and various features from Supabase that we have been wanting to try.
To start, we need to setup our application in Supabase so that we can train our Dreambooth model based on the images in our storage bucket. From Supabase, we will make use of Auth, Database, Storage and Edge functions in order to build our application.
You will need to create an account on Supabase but luckily they have a very generous free tier. We will start by using their React Quickstart which sets up Auth, Database and storage functionality for us. Follow the instructions up to the end of “Initialize React App” and stop before “Set up Login component”. We will not be setting up Auth in this tutorial since it is out of scope.
In your Supabase dashboard, go to your table editor and click the button “New table”. Give it the name filePaths and enable “Row level security” as well as “Realtime”. Insert the following columns into the new table:
We will store the location of our generated images in this table and use the Supabase realtime function to display them on our frontend application.
You would also need to specify the correct RLS (Row Level Security)policies for both images and your database. We defined very simple rules — you can select and insert as long as you are using the ANON key from your dashboard since we use this across our application. Below is an example of us doing it for images.
As we mentioned, Dreambooth performs particularly well generating images around a specific subject. However, we first need to train the model on images of our subject. We created a simple Git repository to do most of the heavy lifting when it comes to training a Dreambooth model. You can clone the repo here to a private repository since you will have credentials stored in the files. You may follow the instructions in the README of the repo or simply follow them below!
You will see in the unprocessed folder is a folder called 12345678. This is on purpose and trains Dreambooth to relate the subject to this number. For example, if I entered the prompt “12345678 in a Christmas hat” it would show results of me in a Christmas hat. If you generate multiple models each with different subjects then you can use a unique folder id to refer to different subjects.
9. You will also need to update the download_images.py and upload_images.py file with your Supabase credentials. You can grab your credentials from settings->Api on your Supabase profile.
10. Run ./run-all.sh
It will now train the model on the images you uploaded and upload the results to Supabase. You should see a result similar to the image below. In order to get it working with Cerebrium, you need to upload it to Huggingface (this is a temporary workflow).
You should see your model available in Hugging Face under your profile.
We know the experience isn’t great to train the Dreambooth model since you have to do a lot of setup of training instances. We are looking at including this functionality in the Cerebrium framework where you will be able to train your model using 1 line of code. If you would like to be notified of when we release this functionality, you can enter your email here.
Cerebrium allows you to deploy ML models to serverless GPUs using one line of code. We automatically handle model versioning, A/B testing, integration with monitoring tools and much much more.
To start you need to create an account here in order to get an API key that links all deployments to your account.
Next, install our Python framework.
In the above, we specify that we want to use the prebuilt configuration for Dreambooth models, give the deployment a name on our dashboard and then enter the API key from our dashboard. Once run, you should receive the endpoint for inference of your deployment.
For Dreambooth, you can define the following parameters:
Now that our model is trained and deployed, we need to tie everything together. We initially did some Supabase setup so now we just need to setup some edge functions and create our frontend React application.
We have to setup two edge functions:
Below is the code for our image webhook that Cerebrium will notify when the images from our Dreambooth model have finished generating. The reason we use an image webhook is that depending on the number of images we generate and the number of training steps we select, it could take some time which means our requests could time out.
We will receive base64 encoded strings of the generated images from Cerebrium, convert them into PNG’s and store them in our storage bucket. We will then update the database with the url’s of the newly added URL’s. You will understand when we get to the frontend why we are adding the URL’s to our database.
Now that our model is trained and deployed, we need to tie everything together. We initially did some Supabase setup so now we just need to setup some edge functions and create our frontend React application.
We have to setup two edge functions:
Below is the code for our image webhook that Cerebrium will notify when the images from our Dreambooth model have finished generating. The reason we use an image webhook is that depending on the number of images we generate and the number of training steps we select, it could take some time which means our requests could time out.
We will receive base64 encoded strings of the generated images from Cerebrium, convert them into PNG’s and store them in our storage bucket. We will then update the database with the url’s of the newly added URL’s. You will understand when we get to the frontend why we are adding the URL’s to our database.
In order to run this locally, you need to create a .env.local file that contains the SUPABASE_URL and SUPABASE_ANON_KEY variables. These are the same credentials you used above for training the Dreambooth model.
In order to deploy this webhook, run the command: supabase functions deploy image-webhook — no-verify-jwt .We use the flag no-verify-jwt since otherwise Supabase requires you to have an Authorization header. This is not neccessary for our use case.
We then need to create a function that will make a request to our Cerebrium model endpoint. Create another Supabase function and then copy the code below:
For the above code snippet, you will need to enter the URL of your image-webhook url. You can find the URL on your Supabase dashboard under Edge functions. It should look similar to https://project-id.functions.supabase.co/image-webhook. You deploy this function using the same command we used above supabase functions deploy cerebrium_endpoint .
You can take a look at our design in our Git repository here. However, the most important element to note in our frontend application is our use of the Supabase realtime function. Our frontend listens to changes specifically in the filePaths table and displays an image every time a file URL gets added to the database. We also make the request to the Cerebrium endpoint when a user clicks the “generate”
To run the frontend application run yarn start .
Supabase has a great integration with Vercel to deploy your application just by connecting your git repo. In some instances, it might have a “deploy” button in the bottom tab of your website.
You can create an account on Vercel here and simply connect your Github repo to deploy your application. In your settings you can define which branch is your production branch. Every time you push changes to the master branch Vercel will automatically build and deploy a new version of you website in a couple of minutes.
Once your application is deployed. You need to go to your Supabase dashboard and navigate to Authentication and then URL configuration. You then need to add the URL of your Vercel application such as “https://my-vercel-website.vercel.app/”.
You have now created your own custom Dreambooth model! You can play with our live version here. There are many enhancements you can make to the product and the quality of images by increasing the number of images and steps used for training.
So to recap we had the following elements of our project in order to create our AvatarAI.me replica.
Cerebrium framework: This allowed us to deploy our custom Dreambooth model to Serverless GPU’s using one line of code.
Training repo: The code used to train our custom dreambooth model on a specific subject and deploy it to Hugging Face.
Supabase application: