jbilcke-hf HF staff commited on
Commit
5b3357c
β€’
1 Parent(s): 95bbb7f

working on adding turbo

Browse files
.env CHANGED
@@ -31,6 +31,9 @@ VC_SDXL_SPACE_API_URL="https://jbilcke-hf-image-server.hf.space"
31
  #--------------------- LCM INFERENCE SERVERS ---------------------
32
  VC_LCM_SPACE_API_URL="https://jbilcke-hf-fast-image-server.hf.space"
33
 
 
 
 
34
  #----------------- ZEROSCOPE INFERENCE SERVERS -------------------
35
  VC_ZEROSCOPE_SPACE_API_URL_1="https://jbilcke-hf-zeroscope-server-1.hf.space"
36
  VC_ZEROSCOPE_SPACE_API_URL_2="https://jbilcke-hf-zeroscope-server-2.hf.space"
 
31
  #--------------------- LCM INFERENCE SERVERS ---------------------
32
  VC_LCM_SPACE_API_URL="https://jbilcke-hf-fast-image-server.hf.space"
33
 
34
+ #--------------------- SDXL TURBO INFERENCE SERVERS ---------------------
35
+ VC_SDXL_TURBO_SPACE_API_URL="https://jbilcke-hf-faster-image-server.hf.space"
36
+
37
  #----------------- ZEROSCOPE INFERENCE SERVERS -------------------
38
  VC_ZEROSCOPE_SPACE_API_URL_1="https://jbilcke-hf-zeroscope-server-1.hf.space"
39
  VC_ZEROSCOPE_SPACE_API_URL_2="https://jbilcke-hf-zeroscope-server-2.hf.space"
src/production/renderImage.mts CHANGED
@@ -1,4 +1,5 @@
1
  import { generateImageLCMAsBase64 } from "../providers/image-generation/generateImageLCMGradio.mts"
 
2
  import { generateImageSDXLAsBase64 } from "../providers/image-generation/generateImageSDXLGradio.mts"
3
  import { generateImageSDXL360AsBase64 } from "../providers/image-generation/generateImageSDXL360.mts"
4
  import { RenderedScene, RenderRequest } from "../types.mts"
@@ -10,10 +11,19 @@ export async function renderImage(
10
 
11
  const isSpherical = request.projection === 'spherical'
12
 
 
 
 
13
  const generateImageAsBase64 = isSpherical
14
  ? generateImageSDXL360AsBase64
15
  : request.turbo
16
- ? generateImageLCMAsBase64
 
 
 
 
 
 
17
  : generateImageSDXLAsBase64
18
 
19
  // console.log(`going to generate an image using ${request.projection || "default (cartesian)"} projection`)
 
1
  import { generateImageLCMAsBase64 } from "../providers/image-generation/generateImageLCMGradio.mts"
2
+ import { generateImageSDXLTurboAsBase64 } from "../providers/image-generation/generateImageSDXLTurbo.mts"
3
  import { generateImageSDXLAsBase64 } from "../providers/image-generation/generateImageSDXLGradio.mts"
4
  import { generateImageSDXL360AsBase64 } from "../providers/image-generation/generateImageSDXL360.mts"
5
  import { RenderedScene, RenderRequest } from "../types.mts"
 
11
 
12
  const isSpherical = request.projection === 'spherical'
13
 
14
+ // we don't want to switch too much between model types in VideoChain,
15
+ // because for speed we need to pre-load the servers,
16
+ // but there is no point in pre-loading many servers for many models
17
  const generateImageAsBase64 = isSpherical
18
  ? generateImageSDXL360AsBase64
19
  : request.turbo
20
+
21
+ // turbo models are models that are slightly less beautiful
22
+ // but much, much faster to run
23
+ // for the moment we use SDXL + LCM, as it offers better scene coherence,
24
+ // but we might switch to SDXL Turbo in the future if its quality improves
25
+ ? generateImageLCMAsBase64 // generateImageSDXLTurboAsBase64
26
+
27
  : generateImageSDXLAsBase64
28
 
29
  // console.log(`going to generate an image using ${request.projection || "default (cartesian)"} projection`)
src/production/renderVideo.mts CHANGED
@@ -1,5 +1,7 @@
1
  import { RenderedScene, RenderRequest } from "../types.mts"
2
- import { generateVideo } from "../providers/video-generation/generateVideoWithZeroscope.mts"
 
 
3
 
4
  export async function renderVideo(
5
  request: RenderRequest,
 
1
  import { RenderedScene, RenderRequest } from "../types.mts"
2
+
3
+ // import { generateVideo } from "../providers/video-generation/generateVideoWithZeroscope.mts"
4
+ import { generateVideo } from "../providers/video-generation/generateVideoWithHotshotGradioAPI.mts"
5
 
6
  export async function renderVideo(
7
  request: RenderRequest,
src/providers/image-generation/generateImageSDXLTurbo.mts ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import { client } from "@gradio/client"
3
+
4
+ import { generateSeed } from "../../utils/misc/generateSeed.mts"
5
+ import { getValidNumber } from "../../utils/validators/getValidNumber.mts"
6
+ import { convertToWebp } from "../../utils/image/convertToWebp.mts"
7
+
8
+
9
+ const instance = `${process.env.VC_SDXL_TURBO_SPACE_API_URL || ""}`
10
+ const secretToken = `${process.env.VC_MICROSERVICE_SECRET_TOKEN || ""}`
11
+
12
+ // console.log("DEBUG:", JSON.stringify({ instances, secretToken }, null, 2))
13
+
14
+ export async function generateImageSDXLTurboAsBase64(options: {
15
+ positivePrompt: string;
16
+ negativePrompt?: string;
17
+ seed?: number;
18
+ width?: number;
19
+ height?: number;
20
+ nbSteps?: number;
21
+ }): Promise<string> {
22
+
23
+ // console.log("querying " + instance)
24
+ const positivePrompt = options?.positivePrompt || ""
25
+ if (!positivePrompt) {
26
+ throw new Error("missing prompt")
27
+ }
28
+
29
+ // the negative prompt CAN be missing, since we use a trick
30
+ // where we make the interface mandatory in the TS doc,
31
+ // but browsers might send something partial
32
+ const negativePrompt = options?.negativePrompt || ""
33
+
34
+ // we treat 0 as meaning "random seed"
35
+ const seed = (options?.seed ? options.seed : 0) || generateSeed()
36
+
37
+ const maxRequestedResolution = 1024
38
+ const maxModelResolution = 512
39
+
40
+ const requestedWidth = getValidNumber(options?.width, 256, maxRequestedResolution, maxModelResolution)
41
+ const requestedHeight = getValidNumber(options?.height, 256, maxRequestedResolution, maxModelResolution)
42
+
43
+ // we try to preserve the original image ratio
44
+ const ratioH = requestedHeight / requestedWidth
45
+ const ratioW = requestedWidth / requestedHeight
46
+
47
+ // we always try to ccrank the resolution to the max
48
+ let width = ratioW < 1 ? Math.round(ratioW * maxModelResolution) : maxModelResolution
49
+ let height = ratioH < 1 ? Math.round(ratioH * maxModelResolution) : maxModelResolution
50
+
51
+ const positive = [
52
+
53
+ // oh well.. is it too late to move this to the bottom?
54
+ "beautiful",
55
+
56
+ // too opinionated, so let's remove it
57
+ // "intricate details",
58
+
59
+ positivePrompt,
60
+
61
+ "award winning",
62
+ "high resolution"
63
+ ].filter(word => word)
64
+ .join(", ")
65
+
66
+ const negative = [
67
+ negativePrompt,
68
+ "watermark",
69
+ "copyright",
70
+ "blurry",
71
+ // "artificial",
72
+ // "cropped",
73
+ "low quality",
74
+ "ugly"
75
+ ].filter(word => word)
76
+ .join(", ")
77
+
78
+ const api = await client(instance, {
79
+ hf_token: `${process.env.VC_HF_API_TOKEN}` as any
80
+ })
81
+
82
+ const rawResponse = (await api.predict("/run", [
83
+ positive, // string in 'Prompt' Textbox component
84
+ negative, // string in 'Negative prompt' Textbox component
85
+ seed, // number (numeric value between 0 and 2147483647) in 'Seed' Slider component
86
+ width, // number (numeric value between 256 and 1024) in 'Width' Slider component
87
+ height, // number (numeric value between 256 and 1024) in 'Height' Slider component
88
+ secretToken
89
+ ])) as any
90
+
91
+ const result = rawResponse?.data?.[0] as string
92
+ if (!result?.length) {
93
+ throw new Error(`the returned image was empty`)
94
+ }
95
+
96
+ try {
97
+ const finalImage = await convertToWebp(result)
98
+ return finalImage
99
+ } catch (err) {
100
+ // console.log("err:", err)
101
+ throw new Error(err)
102
+ }
103
+ }