Skip to content

Commit ecc805e

Browse files
committed
Adds a tutorial for generating images with SDXL
1 parent 77b9db0 commit ecc805e

File tree

1 file changed

+306
-0
lines changed

1 file changed

+306
-0
lines changed
Lines changed: 306 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,306 @@
1+
---
2+
title: Generate images with SDXL Turbo
3+
description: Learn to generate images with SDXL with a frontend web app.
4+
sidebar_position: 2
5+
---
6+
7+
import Tabs from '@theme/Tabs';
8+
import TabItem from '@theme/TabItem';
9+
10+
When it comes to working with an AI image generator, the speed in which images are generated is often a compromise.
11+
RunPod's Serverless Workers allows you to host [SDXL Turbo](https://huggingface.co/stabilityai/sdxl-turbo) from Stability AI, which is a fast text-to-image model.
12+
13+
In this tutorial, you'll build a web application, where you'll leverage RunPod's Serverless Worker and Endpoint to return an image from a text-based input.
14+
15+
By the end of this tutorial, you'll have an understanding of running a Serverless Worker on RunPod and sending requests to an Endpoint to receive a response.
16+
17+
You can proceed with the tutorial by following the build steps outlined here or skip directly to [Deploy the Model](#deploy-the-model) section.
18+
19+
## Prerequisites
20+
21+
This section presumes you have an understanding of the terminal and can execute commands from your terminal.
22+
23+
Before starting this tutorial, you'll need access to:
24+
25+
### RunPod
26+
27+
To continue with this quick start, you'll need access to the following from RunPod:
28+
29+
- RunPod account
30+
- RunPod API Key
31+
32+
### Docker
33+
34+
To build your Docker image, you'll need access to the following:
35+
36+
- Docker installed
37+
- Docker account
38+
39+
You can also use the prebuilt image from [runpod/sdxl-turbo](https://hub.docker.com/r/runpod/sdxl-turbo).
40+
41+
### GitHub
42+
43+
To clone the `worker-sdxl-turbo` repo, you'll need access to the following:
44+
45+
- Git installed
46+
- Permissions to clone GitHub repos
47+
48+
With the prerequisites covered, get started by building and pushing a Docker image to a container registry.
49+
50+
## Build and push your Docker image
51+
52+
This step will walk you through building and pushing your Docker image to your container registry.
53+
This is useful to building custom images for your use case.
54+
If you prefer, you can use the prebuilt image from [runpod/sdxl-turbo](https://hub.docker.com/r/runpod/sdxl-turbo) instead of building your own.
55+
56+
Building a Docker image allows you to specify the container when creating a Worker.
57+
The Docker image includes the [RunPod Handler](https://github.com/runpod-workers/worker-sdxl-turbo/blob/main/src/handler.py) which is how you provide instructions to Worker to perform some task.
58+
In this example, the Handler is responsible for taking a Job and returning a base 64 instance of the image.
59+
60+
1. Clone the [RunPod Worker SDXL Turbo](https://github.com/runpod-workers/worker-sdxl-turbo) repository:
61+
62+
```command
63+
gh repo clone runpod-workers/worker-sdxl-turbo
64+
```
65+
66+
2. Navigate to the root of the cloned repo:
67+
68+
```command
69+
cd worker-sdxl-turbo
70+
```
71+
72+
3. Build the Docker image:
73+
74+
```command
75+
docker build --tag <username>/<repo>:<tag> .
76+
```
77+
78+
4. Push your container registry:
79+
80+
```command
81+
docker push <username>/<repo>:<tag>
82+
```
83+
84+
Now that you've pushed your container registry, you're ready to deploy your Serverless Endpoint to RunPod.
85+
86+
## Deploy a Serverless Endpoint
87+
88+
The container you just built will run on the Worker you're creating.
89+
Here, you will configure and deploy the Endpoint.
90+
This will include the GPU and the storage needed for your Worker.
91+
92+
This step will walk you through deploying a Serverless Endpoint to RunPod.
93+
94+
1. Login to the [RunPod Serverless console](https://www.runpod.io/console/serverless).
95+
2. Select **+ New Endpoint**.
96+
3. Provide the following:
97+
1. Endpoint name.
98+
2. Select a GPU.
99+
3. Configure the number of workers.
100+
4. (optional) Select **FlashBoot**.
101+
5. (optional) Select a template.
102+
6. Enter the name of your Docker image.
103+
- For example, `runpod/sdxl-turbo:latest`.
104+
7. Specify enough memory for your Docker image.
105+
4. Select **Deploy**.
106+
107+
Now, let's send a request to your Endpoint.
108+
109+
## Send a request
110+
111+
Now that our Endpoint is deployed, you can begin interacting with and integrating it into an application.
112+
Before writing the logic into the applicaiton, ensure that you can interact with the Endpoint by sending a request.
113+
114+
Run the following command:
115+
116+
<Tabs>
117+
<TabItem value="curl" label="cURL" default>
118+
119+
```bash
120+
curl -X POST "https://api.runpod.ai/v2/${YOUR_ENDPOINT}/runsync" \
121+
-H "accept: application/json" \
122+
-H "content-type: application/json" \
123+
-H "authorization: ${YOUR_API_KEY}" \
124+
-d '{
125+
"input": {
126+
"prompt": "${YOUR_PROMPT}",
127+
"num_inference_steps": 25,
128+
"refiner_inference_steps": 50,
129+
"width": 1024,
130+
"height": 1024,
131+
"guidance_scale": 7.5,
132+
"strength": 0.3,
133+
"seed": null,
134+
"num_images": 1
135+
}
136+
}'
137+
```
138+
139+
</TabItem>
140+
<TabItem value="output" label="Output">
141+
142+
```json
143+
{
144+
"delayTime": 168,
145+
"executionTime": 251,
146+
"id": "sync-fa542d19-92b2-47d0-8e58-c01878f0365d-u1",
147+
"output": "BASE_64",
148+
"status": "COMPLETED"
149+
}
150+
```
151+
152+
</TabItem>
153+
</Tabs>
154+
155+
Export your variable names in your terminal session or replace them in line:
156+
157+
- `YOUR_ENDPOINT`: The name of your Endpoint.
158+
- `YOUD_API_KEY`: The API Key required with read and write access.
159+
- `YOUR_PROMPT`: The custom prompt passed to the model.
160+
161+
You should se the output. The status will return `PENDING`; but quickly change to `COMPLETED` if you query the Job Id.
162+
163+
## Integrate into your application
164+
165+
Now, let's create a web application that can take advantage of writing a prompt and generate an image based on that prompt.
166+
While these steps are specific to JavaScript, you can make requests against your Endpoint in any language of your choice.
167+
168+
To do that, you'll create two files:
169+
170+
- `index.html`: The frontend to your web application.
171+
- `script.js`: The backend which handles the logic behind getting the prompt and the call to the Serverless Endpoint.
172+
173+
<Tabs>
174+
<TabItem value="html" label="HTML" default>
175+
176+
The HTML file (`index.html`) sets up a user interface with an input box for the prompt and a button to trigger the image generation.
177+
178+
```html
179+
<!-- index.html -->
180+
<!DOCTYPE html>
181+
<html lang="en">
182+
<head>
183+
<meta charset="UTF-8">
184+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
185+
<title>RunPod AI Image Generator</title>
186+
<style>
187+
body {
188+
font-family: Arial, sans-serif;
189+
text-align: center;
190+
padding: 20px;
191+
}
192+
193+
#imageResult {
194+
margin-top: 20px;
195+
}
196+
</style>
197+
</head>
198+
<body>
199+
<h1>RunPod AI Image Generator</h1>
200+
<input type="text" id="promptInput" placeholder="Enter your image prompt" />
201+
<button onclick="generateImage()">Generate Image</button>
202+
203+
<div id="imageResult"></div>
204+
205+
<script src="script.js"></script>
206+
</body>
207+
</html>
208+
```
209+
210+
</TabItem>
211+
<TabItem value="javascript" label="JavaScript">
212+
213+
The JavaScript file (`script.js`) contains the `generateImage` function. This function reads the user's input, makes a POST request to the RunPod serverless endpoint, and handles the response.
214+
The server's response is expected to contain the base64-encoded image, which is then displayed on the webpage.
215+
216+
```javascript
217+
// script.js
218+
async function generateImage() {
219+
const prompt = document.getElementById("promptInput").value;
220+
if (!prompt) {
221+
alert("Please enter a prompt!");
222+
return;
223+
}
224+
225+
const options = {
226+
method: "POST",
227+
headers: {
228+
accept: "application/json",
229+
"content-type": "application/json",
230+
// Replace with your actual API key
231+
authorization: "Bearer ${process.env.REACT_APP_AUTH_TOKEN}",
232+
},
233+
body: JSON.stringify({
234+
input: {
235+
prompt: prompt,
236+
num_inference_steps: 25,
237+
width: 1024,
238+
height: 1024,
239+
guidance_scale: 7.5,
240+
seed: null,
241+
num_images: 1,
242+
},
243+
}),
244+
};
245+
246+
try {
247+
const response = await fetch(
248+
// Replace with your actual Endpoint Id
249+
"https://api.runpod.ai/v2/${process.env.REACT_APP_ENDPOINT_ID}/runsync",
250+
options,
251+
);
252+
const data = await response.json();
253+
if (data && data.output) {
254+
const imageBase64 = data.output;
255+
const imageUrl = `data:image/jpeg;base64,${imageBase64}`;
256+
document.getElementById("imageResult").innerHTML =
257+
`<img src="${imageUrl}" alt="Generated Image" />`;
258+
} else {
259+
alert("Failed to generate image");
260+
}
261+
} catch (error) {
262+
console.error("Error:", error);
263+
alert("Error generating image");
264+
}
265+
}
266+
```
267+
268+
</TabItem>
269+
</Tabs>
270+
271+
1. Replace `${process.env.REACT_APP_AUTH_TOKEN}` with your actual API key.
272+
2. Replace `${process.env.REACT_APP_ENDPOINT_ID}` with your specific Endpoint.
273+
3. Open `index.html` in a web browser, enter a prompt, and click the "Generate Image" button to see the result.
274+
275+
This web application serves as a basic example of how to interact with your RunPod serverless endpoint from a client-side application.
276+
It can be expanded or modified to fit more complex use cases.
277+
278+
## Run a server
279+
280+
You can run a server through Python or by opening the `index.html` page in your browser.
281+
282+
<Tabs>
283+
284+
<TabItem value="python" label="Python" default>
285+
286+
Run the following command to start a server locally using Python.
287+
288+
```python
289+
python -m http.server 8000
290+
```
291+
292+
</TabItem>
293+
294+
<TabItem value="directly" label="File explorer">
295+
296+
**Open the File in a Browser**
297+
298+
Open the `index.html` file directly in your web browser.
299+
300+
1. Navigate to the folder where your `index.html` file is located.
301+
2. Right-click on the file and choose "Open with" and select your preferred web browser.
302+
- Alternatively, you can drag and drop the `index.html` file into an open browser window.
303+
- The URL will look something like `file:///path/to/your/index.html`.
304+
305+
</TabItem>
306+
</Tabs>

0 commit comments

Comments
 (0)