Commit
•
e52146b
1
Parent(s):
166428d
allow support for Inference API for SDXL
Browse files- .env +31 -17
- README.md +17 -6
- src/app/engine/caption.ts +1 -1
- src/app/engine/render.ts +78 -10
- src/app/queries/predict.ts +2 -2
- src/types.ts +2 -0
.env
CHANGED
@@ -1,35 +1,49 @@
|
|
1 |
-
# ------------- IMAGE API CONFIG --------------
|
2 |
# Supported values:
|
3 |
# - VIDEOCHAIN
|
4 |
# - REPLICATE
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
VIDEOCHAIN_API_TOKEN=
|
9 |
-
|
10 |
-
REPLICATE_API_TOKEN=
|
11 |
-
REPLICATE_API_MODEL="stabilityai/sdxl"
|
12 |
-
REPLICATE_API_MODEL_VERSION="da77bc59ee60423279fd632efb4795ab731d9e3ca9705ef3341091fb989b7eaf"
|
13 |
|
14 |
-
# ------------- LLM API CONFIG ----------------
|
15 |
# Supported values:
|
16 |
# - INFERENCE_ENDPOINT
|
17 |
# - INFERENCE_API
|
18 |
-
LLM_ENGINE="
|
|
|
|
|
19 |
|
20 |
-
# Hugging Face token
|
|
|
21 |
HF_API_TOKEN=
|
22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
# URL to a custom text-generation Inference Endpoint of your choice
|
24 |
# -> You can leave it empty if you decide to use an Inference API Model instead
|
25 |
-
|
26 |
|
27 |
# You can also use a model from the Inference API (not a custom inference endpoint)
|
28 |
# -> You can leave it empty if you decide to use an Inference Endpoint URL instead
|
29 |
-
|
30 |
-
|
31 |
-
# Not supported yet
|
32 |
-
OPENAI_TOKEN=
|
33 |
|
34 |
# ----------- COMMUNITY SHARING (OPTIONAL) -----------
|
35 |
NEXT_PUBLIC_ENABLE_COMMUNITY_SHARING="false"
|
|
|
|
|
1 |
# Supported values:
|
2 |
# - VIDEOCHAIN
|
3 |
# - REPLICATE
|
4 |
+
# - INFERENCE_ENDPOINT
|
5 |
+
# - INFERENCE_API
|
6 |
+
RENDERING_ENGINE="INFERENCE_API"
|
|
|
|
|
|
|
|
|
|
|
7 |
|
|
|
8 |
# Supported values:
|
9 |
# - INFERENCE_ENDPOINT
|
10 |
# - INFERENCE_API
|
11 |
+
LLM_ENGINE="INFERENCE_API"
|
12 |
+
|
13 |
+
# ------------- PROVIDER AUTH ------------
|
14 |
|
15 |
+
# Hugging Face token, if you plan to use the Inference API or Inference Endpoint
|
16 |
+
# for the LLM or SDXL generation
|
17 |
HF_API_TOKEN=
|
18 |
|
19 |
+
# Replicate token, if you wish to use them as a provider for SDXL
|
20 |
+
REPLICATE_API_TOKEN=
|
21 |
+
|
22 |
+
# OpenAI is not supported yet
|
23 |
+
OPENAI_TOKEN=
|
24 |
+
|
25 |
+
# VideoChain is a custom API used for SDXL but you don't need it for the base features
|
26 |
+
VIDEOCHAIN_API_TOKEN=
|
27 |
+
|
28 |
+
# ------------- RENDERING API CONFIG --------------
|
29 |
+
|
30 |
+
RENDERING_VIDEOCHAIN_API_URL="http://localhost:7860"
|
31 |
+
|
32 |
+
RENDERING_REPLICATE_API_MODEL="stabilityai/sdxl"
|
33 |
+
RENDERING_REPLICATE_API_MODEL_VERSION="da77bc59ee60423279fd632efb4795ab731d9e3ca9705ef3341091fb989b7eaf"
|
34 |
+
|
35 |
+
RENDERING_HF_INFERENCE_ENDPOINT_URL="https://XXXXXXXXXX.endpoints.huggingface.cloud"
|
36 |
+
RENDERING_HF_INFERENCE_API_MODEL="stabilityai/stable-diffusion-xl-base-1.0"
|
37 |
+
|
38 |
+
# ------------- LLM API CONFIG ----------------
|
39 |
+
|
40 |
# URL to a custom text-generation Inference Endpoint of your choice
|
41 |
# -> You can leave it empty if you decide to use an Inference API Model instead
|
42 |
+
LLM_HF_INFERENCE_ENDPOINT_URL=
|
43 |
|
44 |
# You can also use a model from the Inference API (not a custom inference endpoint)
|
45 |
# -> You can leave it empty if you decide to use an Inference Endpoint URL instead
|
46 |
+
LLM_HF_INFERENCE_API_MODEL="codellama/CodeLlama-7b-hf"
|
|
|
|
|
|
|
47 |
|
48 |
# ----------- COMMUNITY SHARING (OPTIONAL) -----------
|
49 |
NEXT_PUBLIC_ENABLE_COMMUNITY_SHARING="false"
|
README.md
CHANGED
@@ -17,17 +17,28 @@ First, I would like to highlight that everything is open-source (see [here](http
|
|
17 |
However the project isn't a monolithic Space that can be duplicated and ran immediately:
|
18 |
it requires various components to run for the frontend, backend, LLM, SDXL etc.
|
19 |
|
20 |
-
If you try to duplicate the project
|
21 |
|
|
|
22 |
- `LLM_ENGINE`: can be either "INFERENCE_API" or "INFERENCE_ENDPOINT"
|
23 |
-
- `HF_API_TOKEN`: necessary if you decide to use an inference api model or a custom inference endpoint
|
24 |
-
- `HF_INFERENCE_ENDPOINT_URL`: necessary if you decide to use a custom inference endpoint
|
25 |
- `RENDERING_ENGINE`: can only be "VIDEOCHAIN" or "REPLICATE" for now, unless you code your custom solution
|
26 |
-
|
|
|
|
|
27 |
- `VIDEOCHAIN_API_TOKEN`: secret token to access the VideoChain API server
|
28 |
- `REPLICATE_API_TOKEN`: in case you want to use Replicate.com
|
29 |
-
|
30 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
|
32 |
In addition, there are some community sharing variables that you can just ignore.
|
33 |
Those variables are not required to run the AI Comic Factory on your own website or computer
|
|
|
17 |
However the project isn't a monolithic Space that can be duplicated and ran immediately:
|
18 |
it requires various components to run for the frontend, backend, LLM, SDXL etc.
|
19 |
|
20 |
+
If you try to duplicate the project, open the `.env` you will see it requires some variables.
|
21 |
|
22 |
+
Provider config:
|
23 |
- `LLM_ENGINE`: can be either "INFERENCE_API" or "INFERENCE_ENDPOINT"
|
|
|
|
|
24 |
- `RENDERING_ENGINE`: can only be "VIDEOCHAIN" or "REPLICATE" for now, unless you code your custom solution
|
25 |
+
|
26 |
+
Auth config:
|
27 |
+
- `HF_API_TOKEN`: necessary if you decide to use an inference api model or a custom inference endpoint
|
28 |
- `VIDEOCHAIN_API_TOKEN`: secret token to access the VideoChain API server
|
29 |
- `REPLICATE_API_TOKEN`: in case you want to use Replicate.com
|
30 |
+
|
31 |
+
Rendering config:
|
32 |
+
- `RENDERING_HF_INFERENCE_ENDPOINT_URL`: necessary if you decide to use a custom inference endpoint
|
33 |
+
- `RENDERING_REPLICATE_API_MODEL_VERSION`: url to the VideoChain API server
|
34 |
+
- `RENDERING_HF_INFERENCE_ENDPOINT_URL`: optional, default to nothing
|
35 |
+
- `RENDERING_HF_INFERENCE_API_MODEL`: optional, defaults to "stabilityai/stable-diffusion-xl-base-1.0"
|
36 |
+
- `RENDERING_REPLICATE_API_MODEL`: optional, defaults to "stabilityai/sdxl"
|
37 |
+
- `RENDERING_REPLICATE_API_MODEL_VERSION`: optional, in case you want to change the version
|
38 |
+
|
39 |
+
Language model config:
|
40 |
+
- `LLM_HF_INFERENCE_ENDPOINT_URL`: "https://llama-v2-70b-chat.ngrok.io"
|
41 |
+
- `LLM_HF_INFERENCE_API_MODEL`: "codellama/CodeLlama-7b-hf"
|
42 |
|
43 |
In addition, there are some community sharing variables that you can just ignore.
|
44 |
Those variables are not required to run the AI Comic Factory on your own website or computer
|
src/app/engine/caption.ts
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
import { ImageAnalysisRequest, ImageAnalysisResponse } from "@/types"
|
4 |
|
5 |
-
const apiUrl = `${process.env.
|
6 |
|
7 |
export async function see({
|
8 |
prompt,
|
|
|
2 |
|
3 |
import { ImageAnalysisRequest, ImageAnalysisResponse } from "@/types"
|
4 |
|
5 |
+
const apiUrl = `${process.env.RENDERING_VIDEOCHAIN_API_URL || ""}`
|
6 |
|
7 |
export async function see({
|
8 |
prompt,
|
src/app/engine/render.ts
CHANGED
@@ -1,6 +1,7 @@
|
|
1 |
"use server"
|
2 |
|
3 |
-
import
|
|
|
4 |
|
5 |
import { RenderRequest, RenderedScene, RenderingEngine } from "@/types"
|
6 |
import { generateSeed } from "@/lib/generateSeed"
|
@@ -8,13 +9,15 @@ import { sleep } from "@/lib/sleep"
|
|
8 |
|
9 |
const renderingEngine = `${process.env.RENDERING_ENGINE || ""}` as RenderingEngine
|
10 |
|
11 |
-
const
|
12 |
-
const replicateModel = `${process.env.REPLICATE_API_MODEL || ""}`
|
13 |
-
const replicateModelVersion = `${process.env.REPLICATE_API_MODEL_VERSION || ""}`
|
14 |
|
15 |
-
|
16 |
-
|
17 |
-
const
|
|
|
|
|
|
|
|
|
18 |
|
19 |
export async function newRender({
|
20 |
prompt,
|
@@ -79,9 +82,74 @@ export async function newRender({
|
|
79 |
maskUrl: "",
|
80 |
segments: []
|
81 |
} as RenderedScene
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
} else {
|
83 |
// console.log(`calling POST ${apiUrl}/render with prompt: ${prompt}`)
|
84 |
-
const res = await fetch(`${
|
85 |
method: "POST",
|
86 |
headers: {
|
87 |
Accept: "application/json",
|
@@ -202,7 +270,7 @@ export async function getRender(renderId: string) {
|
|
202 |
} as RenderedScene
|
203 |
} else {
|
204 |
// console.log(`calling GET ${apiUrl}/render with renderId: ${renderId}`)
|
205 |
-
const res = await fetch(`${
|
206 |
method: "GET",
|
207 |
headers: {
|
208 |
Accept: "application/json",
|
@@ -255,7 +323,7 @@ export async function upscaleImage(image: string): Promise<{
|
|
255 |
|
256 |
try {
|
257 |
// console.log(`calling GET ${apiUrl}/render with renderId: ${renderId}`)
|
258 |
-
const res = await fetch(`${
|
259 |
method: "POST",
|
260 |
headers: {
|
261 |
Accept: "application/json",
|
|
|
1 |
"use server"
|
2 |
|
3 |
+
import { v4 as uuidv4 } from "uuid"
|
4 |
+
import Replicate from "replicate"
|
5 |
|
6 |
import { RenderRequest, RenderedScene, RenderingEngine } from "@/types"
|
7 |
import { generateSeed } from "@/lib/generateSeed"
|
|
|
9 |
|
10 |
const renderingEngine = `${process.env.RENDERING_ENGINE || ""}` as RenderingEngine
|
11 |
|
12 |
+
const videochainApiUrl = `${process.env.RENDERING_VIDEOCHAIN_API_URL || "" }`
|
|
|
|
|
13 |
|
14 |
+
const huggingFaceToken = `${process.env.HF_API_TOKEN || ""}`
|
15 |
+
const huggingFaceInferenceEndpointUrl = `${process.env.RENDERING_HF_INFERENCE_ENDPOINT_URL || ""}`
|
16 |
+
const huggingFaceInferenceApiModel = `${process.env.RENDERING_HF_INFERENCE_API_MODEL || ""}`
|
17 |
+
|
18 |
+
const replicateToken = `${process.env.RENDERING_REPLICATE_API_TOKEN || ""}`
|
19 |
+
const replicateModel = `${process.env.RENDERING_REPLICATE_API_MODEL || ""}`
|
20 |
+
const replicateModelVersion = `${process.env.RENDERING_REPLICATE_API_MODEL_VERSION || ""}`
|
21 |
|
22 |
export async function newRender({
|
23 |
prompt,
|
|
|
82 |
maskUrl: "",
|
83 |
segments: []
|
84 |
} as RenderedScene
|
85 |
+
} if (renderingEngine === "INFERENCE_ENDPOINT" || renderingEngine === "INFERENCE_API") {
|
86 |
+
if (!huggingFaceToken) {
|
87 |
+
throw new Error(`you need to configure your HF_API_TOKEN in order to use the ${renderingEngine} rendering engine`)
|
88 |
+
}
|
89 |
+
if (renderingEngine === "INFERENCE_ENDPOINT" && !huggingFaceInferenceEndpointUrl) {
|
90 |
+
throw new Error(`you need to configure your RENDERING_HF_INFERENCE_ENDPOINT_URL in order to use the INFERENCE_ENDPOINT rendering engine`)
|
91 |
+
}
|
92 |
+
if (renderingEngine === "INFERENCE_API" && !huggingFaceInferenceApiModel) {
|
93 |
+
throw new Error(`you need to configure your RENDERING_HF_INFERENCE_API_MODEL in order to use the INFERENCE_API rendering engine`)
|
94 |
+
}
|
95 |
+
|
96 |
+
const seed = generateSeed()
|
97 |
+
|
98 |
+
const url = renderingEngine === "INFERENCE_ENDPOINT"
|
99 |
+
? huggingFaceInferenceEndpointUrl
|
100 |
+
: `https://api-inference.huggingface.co/models/${huggingFaceInferenceApiModel}`
|
101 |
+
|
102 |
+
const res = await fetch(url, {
|
103 |
+
method: "POST",
|
104 |
+
headers: {
|
105 |
+
// Accept: "application/json",
|
106 |
+
"Content-Type": "application/json",
|
107 |
+
Authorization: `Bearer ${huggingFaceToken}`,
|
108 |
+
},
|
109 |
+
body: JSON.stringify({
|
110 |
+
inputs: [
|
111 |
+
"beautiful",
|
112 |
+
"intricate details",
|
113 |
+
prompt,
|
114 |
+
"award winning",
|
115 |
+
"high resolution"
|
116 |
+
].join(", "),
|
117 |
+
parameters: {
|
118 |
+
num_inference_steps: 25,
|
119 |
+
guidance_scale: 8,
|
120 |
+
width,
|
121 |
+
height,
|
122 |
+
|
123 |
+
}
|
124 |
+
}),
|
125 |
+
cache: "no-store",
|
126 |
+
// we can also use this (see https://vercel.com/blog/vercel-cache-api-nextjs-cache)
|
127 |
+
// next: { revalidate: 1 }
|
128 |
+
})
|
129 |
+
|
130 |
+
|
131 |
+
// Recommendation: handle errors
|
132 |
+
if (res.status !== 200) {
|
133 |
+
// This will activate the closest `error.js` Error Boundary
|
134 |
+
throw new Error('Failed to fetch data')
|
135 |
+
}
|
136 |
+
|
137 |
+
// the result is a JSON-encoded string
|
138 |
+
const response = await res.json() as string
|
139 |
+
const assetUrl = `data:image/png;base64,${response}`
|
140 |
+
|
141 |
+
return {
|
142 |
+
renderId: uuidv4(),
|
143 |
+
status: "completed",
|
144 |
+
assetUrl,
|
145 |
+
alt: prompt,
|
146 |
+
error: "",
|
147 |
+
maskUrl: "",
|
148 |
+
segments: []
|
149 |
+
} as RenderedScene
|
150 |
} else {
|
151 |
// console.log(`calling POST ${apiUrl}/render with prompt: ${prompt}`)
|
152 |
+
const res = await fetch(`${videochainApiUrl}/render`, {
|
153 |
method: "POST",
|
154 |
headers: {
|
155 |
Accept: "application/json",
|
|
|
270 |
} as RenderedScene
|
271 |
} else {
|
272 |
// console.log(`calling GET ${apiUrl}/render with renderId: ${renderId}`)
|
273 |
+
const res = await fetch(`${videochainApiUrl}/render/${renderId}`, {
|
274 |
method: "GET",
|
275 |
headers: {
|
276 |
Accept: "application/json",
|
|
|
323 |
|
324 |
try {
|
325 |
// console.log(`calling GET ${apiUrl}/render with renderId: ${renderId}`)
|
326 |
+
const res = await fetch(`${videochainApiUrl}/upscale`, {
|
327 |
method: "POST",
|
328 |
headers: {
|
329 |
Accept: "application/json",
|
src/app/queries/predict.ts
CHANGED
@@ -8,8 +8,8 @@ const hf = new HfInference(process.env.HF_API_TOKEN)
|
|
8 |
|
9 |
// note: we always try "inference endpoint" first
|
10 |
const llmEngine = `${process.env.LLM_ENGINE || ""}` as LLMEngine
|
11 |
-
const inferenceEndpoint = `${process.env.
|
12 |
-
const inferenceModel = `${process.env.
|
13 |
|
14 |
let hfie: HfInferenceEndpoint
|
15 |
|
|
|
8 |
|
9 |
// note: we always try "inference endpoint" first
|
10 |
const llmEngine = `${process.env.LLM_ENGINE || ""}` as LLMEngine
|
11 |
+
const inferenceEndpoint = `${process.env.LLM_HF_INFERENCE_ENDPOINT_URL || ""}`
|
12 |
+
const inferenceModel = `${process.env.LLM_HF_INFERENCE_API_MODEL || ""}`
|
13 |
|
14 |
let hfie: HfInferenceEndpoint
|
15 |
|
src/types.ts
CHANGED
@@ -91,6 +91,8 @@ export type RenderingEngine =
|
|
91 |
| "VIDEOCHAIN"
|
92 |
| "OPENAI"
|
93 |
| "REPLICATE"
|
|
|
|
|
94 |
|
95 |
export type PostVisibility =
|
96 |
| "featured" // featured by admins
|
|
|
91 |
| "VIDEOCHAIN"
|
92 |
| "OPENAI"
|
93 |
| "REPLICATE"
|
94 |
+
| "INFERENCE_API"
|
95 |
+
| "INFERENCE_ENDPOINT"
|
96 |
|
97 |
export type PostVisibility =
|
98 |
| "featured" // featured by admins
|