如何在 Hugging Face Spaces 上用 Gradio 免费运行 ComfyUI 工作流
Run ComfyUI workflows for free with Gradio on Hugging Face Spaces
Hugging Face 发布教程,讲解如何将 ComfyUI 工作流转换为 Gradio 应用并部署到 Spaces 的 ZeroGPU 免费运行。
教程给出从 ComfyUI 工作流导出 Python、封装 Gradio 并部署到 Spaces ZeroGPU 的完整步骤,方法可直接复用。
目录:
- Intro
- 将你的 ComfyUI 工作流导出为纯 Python 运行
- 为你的 ComfyUI 应用创建 Gradio 应用
- 准备在 Hugging Face Spaces 上运行
- 导出到 Spaces 并在 ZeroGPU 上运行
- 结语
简介
在本教程中,我将逐步介绍如何将复杂的 ComfyUI 工作流转换为简单的 Gradio 应用,以及如何将此应用部署到 Hugging Face Spaces ZeroGPU 无服务器架构上,从而可以免费以无服务器方式部署和运行。在本教程中,我们将使用 Nathan Shipley 的 Flux[dev] Redux + Flux[dev] Depth ComfyUI 工作流,但你可以按照本教程使用任何你想要的工作流。
本教程将涵盖的内容简要总结如下:
- 使用
ComfyUI-to-Python-Extension导出你的 ComfyUI 工作流; - 为导出的 Python 创建 Gradio 应用;
- 使用 ZeroGPU 将其部署到 Hugging Face Spaces;
- 即将推出:整个流程将实现自动化;
前提条件
- 了解如何运行 ComfyUI:本教程要求你能够获取一个 ComfyUI 工作流并在你的机器上运行它,安装缺失的节点并找到缺失的模型(不过我们计划很快自动化这一步);
- 将你想要导出的工作流运行起来(如果你想在没有具体工作流的情况下学习,可以随意获取并运行 Nathan Shipley 的 Flux[dev] Redux + Flux[dev] Depth ComfyUI 工作流);
- 具备一点编程知识:但我鼓励初学者尝试跟随本教程,因为无需太多编程基础,它就可以作为 Python、Gradio 和 Spaces 的绝佳入门。
(如果你正在寻找一种端到端的“工作流到应用”结构,无需设置和运行 Comfy 或了解编程,请关注我在 Hugging Face 或 Twitter/X 上的个人资料,因为我们计划在 2025 年初实现这一点!)。
1. 将你的 ComfyUI 工作流导出为纯 Python 运行
ComfyUI 非常棒,而且顾名思义,它包含一个 UI。但 Comfy 远不止是一个 UI,它还包含自己的后端,运行在 Python 上。由于本教程的目的不是使用 Comfy 基于节点的 UI,我们需要将代码导出为纯 Python 运行。
幸运的是,Peyton DeNiro 创建了这个令人惊叹的 ComfyUI-to-Python-Extension,它可以将任何 Comfy 工作流导出为 Python 脚本,让你无需启动 UI 即可运行工作流。
安装该扩展最简单的方法是:(1) 在 ComfyUI Manager 扩展的自定义节点管理器菜单中搜索 ComfyUI to Python Extension,(2) 安装它。然后,为了让该选项出现,你必须 (3) 进入 UI 右下角的设置,(4) 禁用新菜单,(5) 点击 Save as Script。这样,你就会得到一个 Python 脚本。
2. 为导出的 Python 创建 Gradio 应用
现在我们有了 Python 脚本,是时候创建将协调它的 Gradio 应用了。Gradio 是一个 Python 原生的 Web UI 构建器,允许我们创建精简的应用。如果你还没有安装它,可以在你的 Python 环境中使用 pip install gradio 安装
接下来,我们需要稍微重新整理我们的 Python 脚本,以便为它创建一个 UI。
提示:像 ChatGPT、Claude、Qwen、Gemini、LLama 3 等 LLM 都知道如何创建 Gradio 应用。把你导出的 Python 脚本粘贴给它,并要求它创建一个 Gradio 应用,基本上是可以用的,但你可能需要借助本教程中学到的知识来修正一些问题。就本教程而言,我们将自己创建这个应用。
打开导出的 Python 脚本,并为 Gradio 添加一个 import
import os
import random
import sys
from typing import Sequence, Mapping, Any, Union
import torch
+ import gradio as gr
现在,我们需要考虑 UI——我们想在 UI 中暴露复杂 ComfyUI 工作流中的哪些参数?对于 Flux[dev] Redux + Flux[dev] Depth ComfyUI workflow,我想暴露:提示词、结构图像、风格图像、深度强度(用于结构)以及风格强度。
视频展示了哪些节点将暴露给最终用户
为此,一个最小的 Gradio 应用会是:
if __name__ == "__main__":
# Comment out the main() call in the exported Python code
# Start your Gradio app
with gr.Blocks() as app:
# Add a title
gr.Markdown("# FLUX Style Shaping")
with gr.Row():
with gr.Column():
# Add an input
prompt_input = gr.Textbox(label="Prompt", placeholder="Enter your prompt here...")
# Add a `Row` to include the groups side by side
with gr.Row():
# First group includes structure image and depth strength
with gr.Group():
structure_image = gr.Image(label="Structure Image", type="filepath")
depth_strength = gr.Slider(minimum=0, maximum=50, value=15, label="Depth Strength")
# Second group includes style image and style strength
with gr.Group():
style_image = gr.Image(label="Style Image", type="filepath")
style_strength = gr.Slider(minimum=0, maximum=1, value=0.5, label="Style Strength")
# The generate button
generate_btn = gr.Button("Generate")
with gr.Column():
# The output image
output_image = gr.Image(label="Generated Image")
# When clicking the button, it will trigger the `generate_image` function, with the respective inputs
# and the output an image
generate_btn.click(
fn=generate_image,
inputs=[prompt_input, structure_image, style_image, depth_strength, style_strength],
outputs=[output_image]
)
app.launch(share=True)
这是应用渲染后的样子
但如果你尝试运行它,它还不能工作,因为现在我们需要通过修改导出的 python def main() 函数来设置这个 generate_image 函数
脚本:
- def main():
+ def generate_image(prompt, structure_image, style_image, depth_strength, style_strength)
并且在函数内部,我们需要找到我们想要的节点的硬编码值,并将其替换为我们想要控制的变量,例如:
loadimage_429 = loadimage.load_image(
- image="7038548d-d204-4810-bb74-d1dea277200a.png"
+ image=structure_image
)
# ...
loadimage_440 = loadimage.load_image(
- image="2013_CKS_01180_0005_000(the_court_of_pir_budaq_shiraz_iran_circa_1455-60074106).jpg"
+ image=style_image
)
# ...
fluxguidance_430 = fluxguidance.append(
- guidance=15,
+ guidance=depth_strength,
conditioning=get_value_at_index(cliptextencode_174, 0)
)
# ...
stylemodelapplyadvanced_442 = stylemodelapplyadvanced.apply_stylemodel(
- strength=0.5,
+ strength=style_strength,
conditioning=get_value_at_index(instructpixtopixconditioning_431, 0),
style_model=get_value_at_index(stylemodelloader_441, 0),
clip_vision_output=get_value_at_index(clipvisionencode_439, 0),
)
# ...
cliptextencode_174 = cliptextencode.encode(
- text="a girl looking at a house on fire",
+ text=prompt,
clip=get_value_at_index(cr_clip_input_switch_319, 0),
)
而对于我们的输出,我们需要找到保存图像输出节点,并导出其路径,例如:
saveimage_327 = saveimage.save_images(
filename_prefix=get_value_at_index(cr_text_456, 0),
images=get_value_at_index(vaedecode_321, 0),
)
+ saved_path = f"output/{saveimage_327['ui']['images'][0]['filename']}"
+ return saved_path
查看这些修改的视频讲解:
现在,我们应该可以运行代码了!将你的 python 文件保存为 app.py,将其添加到你的 ComfyUI 文件夹根目录,并按以下方式运行
python app.py
就这样,你应该能够在 http://0.0.0.0:7860 上运行你的 Gradio 应用了
* Running on local URL: http://127.0.0.1:7860
* Running on public URL: https://366fdd17b8a9072899.gradio.live
要调试此过程,请在此处查看由 ComfyUI-to-Python-Extension 导出的原始 python 文件与 Gradio 应用之间的差异。你也可以在该 URL 下载两者,以便与自己的工作流程进行检查和比较。
就是这样,恭喜!你成功将你的 ComfyUI 工作流转换为 Gradio 应用。你可以在本地运行它,甚至可以将 URL 发送给客户或朋友,但是,如果你关闭计算机或超过 72 小时,临时 Gradio 链接将失效。对于托管应用的持久结构——包括允许人们以无服务器方式免费运行它,你可以使用 Hugging Face Spaces。
3. 准备在 Hugging Face Spaces 上运行
现在我们的 Gradio 演示已经可以工作,我们可能很想直接把所有内容上传到 Hugging Face Spaces。然而,这需要将数十 GB 的模型上传到 Hugging Face,这不仅速度慢,而且没有必要,因为所有这些模型都已经存在于 Hugging Face 上!
相反,如果我们还没有安装 pip install huggingface_hub,我们会先安装它,然后需要在我们的 app.py 文件顶部执行以下操作:
from huggingface_hub import hf_hub_download
hf_hub_download(repo_id="black-forest-labs/FLUX.1-Redux-dev", filename="flux1-redux-dev.safetensors", local_dir="models/style_models")
hf_hub_download(repo_id="black-forest-labs/FLUX.1-Depth-dev", filename="flux1-depth-dev.safetensors", local_dir="models/diffusion_models")
hf_hub_download(repo_id="Comfy-Org/sigclip_vision_384", filename="sigclip_vision_patch14_384.safetensors", local_dir="models/clip_vision")
hf_hub_download(repo_id="Kijai/DepthAnythingV2-safetensors", filename="depth_anything_v2_vitl_fp32.safetensors", local_dir="models/depthanything")
hf_hub_download(repo_id="black-forest-labs/FLUX.1-dev", filename="ae.safetensors", local_dir="models/vae/FLUX1")
hf_hub_download(repo_id="comfyanonymous/flux_text_encoders", filename="clip_l.safetensors", local_dir="models/text_encoders")
hf_hub_download(repo_id="comfyanonymous/flux_text_encoders", filename="t5xxl_fp16.safetensors", local_dir="models/text_encoders/t5")
这会将 ComfyUI 上的所有本地模型映射到它们的 Hugging Face 版本。不幸的是,目前没有办法自动化这个过程,你需要在 Hugging Face 上找到你的工作流中的模型,并将其映射到相同的 ComfyUI 文件夹。
如果你运行的模型不在 Hugging Face 上,你需要找到一种方法,通过 Python 代码以编程方式将它们下载到正确的文件夹。这将在 Hugging Face Space 启动时仅运行一次。
现在,我们将对 app.py 文件做最后一次修改,即包含 ZeroGPU 的函数装饰器,这将让我们免费进行推理!
import gradio as gr
from huggingface_hub import hf_hub_download
+ import spaces
# ...
+ @spaces.GPU(duration=60) #modify the duration for the average it takes for your worflow to run, in seconds
def generate_image(prompt, structure_image, style_image, depth_strength, style_strength):
在此处查看从之前的 Gradio 演示到准备好 Spaces 更改的差异。
4. 导出到 Spaces 并在 ZeroGPU 上运行
代码已经准备好了——你可以在本地运行,也可以在你偏好的任何云服务中运行——包括专用的 Hugging Face Spaces GPU。但要在无服务器的 ZeroGPU 上运行,请按照下面的步骤操作。
修复依赖项
首先,你需要修改你的 requirements.txt,以包含 custom_nodes 文件夹中的依赖项。由于 Hugging Face Spaces 要求单个 requirements.txt 文件,请确保将此工作流各节点的依赖项添加到根文件夹的 requirements.txt 中。
参见下图,所有 custom_nodes 都需要重复相同的过程:
现在我们准备好了!
- 前往 https://huggingface.co 并创建一个新的 Space。
- 将其硬件设置为 ZeroGPU(如果你是 Hugging Face PRO 订阅者)或者设置为 CPU basic(如果你不是 PRO 用户)(如果你不是 PRO,最后还需要额外一步)。 2.1(如果你更倾向于使用付费的专用 GPU,请选择 L4、L40S、A100 而不是 ZeroGPU,那是付费选项)
- 点击 Files 选项卡,Add
File > Upload Files。拖入你 ComfyUI 文件夹中的所有文件,除了models文件夹(如果你尝试上传models文件夹,上传会失败),这就是为什么我们需要第 3 部分。 - 点击页面底部的
Commit changes to main按钮,等待所有内容上传完成 - 如果你使用的是受限模型(如 FLUX),你需要在设置中包含一个 Hugging Face token。首先,在此处创建一个对你需要的所有受限模型具有
read访问权限的 token,然后转到你的 Space 的Settings页面,创建一个名为HF_TOKEN的新 secret,其值为你刚刚创建的 token。
将模型移到被装饰函数之外(仅限 ZeroGPU)
你的 demo 应该已经可以运行了,但是在当前设置下,每次运行时模型都会从磁盘完整加载到 GPU。为了利用无服务器 ZeroGPU 的高效性,我们需要将所有模型声明从被装饰函数中移到 Python 的全局上下文中。让我们编辑 app.py 函数来实现这一点。
@@ -4,6 +4,7 @@
from typing import Sequence, Mapping, Any, Union
import torch
import gradio as gr
from huggingface_hub import hf_hub_download
+from comfy import model_management
import spaces
hf_hub_download(repo_id="black-forest-labs/FLUX.1-Redux-dev", filename="flux1-redux-dev.safetensors", local_dir="models/style_models")
@@ -109,6 +110,62 @@
from nodes import NODE_CLASS_MAPPINGS
+intconstant = NODE_CLASS_MAPPINGS["INTConstant"]()
+dualcliploader = NODE_CLASS_MAPPINGS["DualCLIPLoader"]()
+dualcliploader_357 = dualcliploader.load_clip(
+ clip_name1="t5/t5xxl_fp16.safetensors",
+ clip_name2="clip_l.safetensors",
+ type="flux",
+)
+cr_clip_input_switch = NODE_CLASS_MAPPINGS["CR Clip Input Switch"]()
+cliptextencode = NODE_CLASS_MAPPINGS["CLIPTextEncode"]()
+loadimage = NODE_CLASS_MAPPINGS["LoadImage"]()
+imageresize = NODE_CLASS_MAPPINGS["ImageResize+"]()
+getimagesizeandcount = NODE_CLASS_MAPPINGS["GetImageSizeAndCount"]()
+vaeloader = NODE_CLASS_MAPPINGS["VAELoader"]()
+vaeloader_359 = vaeloader.load_vae(vae_name="FLUX1/ae.safetensors")
+vaeencode = NODE_CLASS_MAPPINGS["VAEEncode"]()
+unetloader = NODE_CLASS_MAPPINGS["UNETLoader"]()
+unetloader_358 = unetloader.load_unet(
+ unet_name="flux1-depth-dev.safetensors", weight_dtype="default"
+)
+ksamplerselect = NODE_CLASS_MAPPINGS["KSamplerSelect"]()
+randomnoise = NODE_CLASS_MAPPINGS["RandomNoise"]()
+fluxguidance = NODE_CLASS_MAPPINGS["FluxGuidance"]()
+depthanything_v2 = NODE_CLASS_MAPPINGS["DepthAnything_V2"]()
+downloadandloaddepthanythingv2model = NODE_CLASS_MAPPINGS[
+ "DownloadAndLoadDepthAnythingV2Model"
+]()
+downloadandloaddepthanythingv2model_437 = (
+ downloadandloaddepthanythingv2model.loadmodel(
+ model="depth_anything_v2_vitl_fp32.safetensors"
+ )
+)
+instructpixtopixconditioning = NODE_CLASS_MAPPINGS[
+ "InstructPixToPixConditioning"
+]()
+text_multiline_454 = text_multiline.text_multiline(text="FLUX_Redux")
+clipvisionloader = NODE_CLASS_MAPPINGS["CLIPVisionLoader"]()
+clipvisionloader_438 = clipvisionloader.load_clip(
+ clip_name="sigclip_vision_patch14_384.safetensors"
+)
+clipvisionencode = NODE_CLASS_MAPPINGS["CLIPVisionEncode"]()
+stylemodelloader = NODE_CLASS_MAPPINGS["StyleModelLoader"]()
+stylemodelloader_441 = stylemodelloader.load_style_model(
+ style_model_name="flux1-redux-dev.safetensors"
+)
+text_multiline = NODE_CLASS_MAPPINGS["Text Multiline"]()
+emptylatentimage = NODE_CLASS_MAPPINGS["EmptyLatentImage"]()
+cr_conditioning_input_switch = NODE_CLASS_MAPPINGS[
+ "CR Conditioning Input Switch"
+]()
+cr_model_input_switch = NODE_CLASS_MAPPINGS["CR Model Input Switch"]()
+stylemodelapplyadvanced = NODE_CLASS_MAPPINGS["StyleModelApplyAdvanced"]()
+basicguider = NODE_CLASS_MAPPINGS["BasicGuider"]()
+basicscheduler = NODE_CLASS_MAPPINGS["BasicScheduler"]()
+samplercustomadvanced = NODE_CLASS_MAPPINGS["SamplerCustomAdvanced"]()
+vaedecode = NODE_CLASS_MAPPINGS["VAEDecode"]()
+saveimage = NODE_CLASS_MAPPINGS["SaveImage"]()
+imagecrop = NODE_CLASS_MAPPINGS["ImageCrop+"]()
@@ -117,75 +174,6 @@
def generate_image(prompt, structure_image, style_image, depth_strength, style_strength):
import_custom_nodes()
with torch.inference_mode():
- intconstant = NODE_CLASS_MAPPINGS["INTConstant"]()
intconstant_83 = intconstant.get_value(value=1024)
intconstant_84 = intconstant.get_value(value=1024)
- dualcliploader = NODE_CLASS_MAPPINGS["DualCLIPLoader"]()
- dualcliploader_357 = dualcliploader.load_clip(
- clip_name1="t5/t5xxl_fp16.safetensors",
- clip_name2="clip_l.safetensors",
- type="flux",
- )
-
- cr_clip_input_switch = NODE_CLASS_MAPPINGS["CR Clip Input Switch"]()
cr_clip_input_switch_319 = cr_clip_input_switch.switch(
Input=1,
clip1=get_value_at_index(dualcliploader_357, 0),
clip2=get_value_at_index(dualcliploader_357, 0),
)
- cliptextencode = NODE_CLASS_MAPPINGS["CLIPTextEncode"]()
cliptextencode_174 = cliptextencode.encode(
text=prompt,
clip=get_value_at_index(cr_clip_input_switch_319, 0),
)
cliptextencode_175 = cliptextencode.encode(
text="purple", clip=get_value_at_index(cr_clip_input_switch_319, 0)
)
- loadimage = NODE_CLASS_MAPPINGS["LoadImage"]()
loadimage_429 = loadimage.load_image(image=structure_image)
- imageresize = NODE_CLASS_MAPPINGS["ImageResize+"]()
imageresize_72 = imageresize.execute(
width=get_value_at_index(intconstant_83, 0),
height=get_value_at_index(intconstant_84, 0),
interpolation="bicubic",
method="keep proportion",
condition="always",
multiple_of=16,
image=get_value_at_index(loadimage_429, 0),
)
- getimagesizeandcount = NODE_CLASS_MAPPINGS["GetImageSizeAndCount"]()
getimagesizeandcount_360 = getimagesizeandcount.getsize(
image=get_value_at_index(imageresize_72, 0)
)
- vaeloader = NODE_CLASS_MAPPINGS["VAELoader"]()
- vaeloader_359 = vaeloader.load_vae(vae_name="FLUX1/ae.safetensors")
- vaeencode = NODE_CLASS_MAPPINGS["VAEEncode"]()
vaeencode_197 = vaeencode.encode(
pixels=get_value_at_index(getimagesizeandcount_360, 0),
vae=get_value_at_index(vaeloader_359, 0),
)
- unetloader = NODE_CLASS_MAPPINGS["UNETLoader"]()
- unetloader_358 = unetloader.load_unet(
- unet_name="flux1-depth-dev.safetensors", weight_dtype="default"
- )
- ksamplerselect = NODE_CLASS_MAPPINGS["KSamplerSelect"]()
ksamplerselect_363 = ksamplerselect.get_sampler(sampler_name="euler")
- randomnoise = NODE_CLASS_MAPPINGS["RandomNoise"]()
randomnoise_365 = randomnoise.get_noise(noise_seed=random.randint(1, 2**64))
- fluxguidance = NODE_CLASS_MAPPINGS["FluxGuidance"]()
fluxguidance_430 = fluxguidance.append(
guidance=15, conditioning=get_value_at_index(cliptextencode_174, 0)
)
- downloadandloaddepthanythingv2model = NODE_CLASS_MAPPINGS[
- "DownloadAndLoadDepthAnythingV2Model"
- ]()
- downloadandloaddepthanythingv2model_437 = (
- downloadandloaddepthanythingv2model.loadmodel(
- model="depth_anything_v2_vitl_fp32.safetensors"
- )
- )
- depthanything_v2 = NODE_CLASS_MAPPINGS["DepthAnything_V2"]()
depthanything_v2_436 = depthanything_v2.process(
da_model=get_value_at_index(downloadandloaddepthanythingv2model_437, 0),
images=get_value_at_index(getimagesizeandcount_360, 0),
)
- instructpixtopixconditioning = NODE_CLASS_MAPPINGS[
- "InstructPixToPixConditioning"
- ]()
instructpixtopixconditioning_431 = instructpixtopixconditioning.encode(
positive=get_value_at_index(fluxguidance_430, 0),
negative=get_value_at_index(cliptextencode_175, 0),
vae=get_value_at_index(vaeloader_359, 0),
pixels=get_value_at_index(depthanything_v2_436, 0),
)
- clipvisionloader = NODE_CLASS_MAPPINGS["CLIPVisionLoader"]()
- clipvisionloader_438 = clipvisionloader.load_clip(
- clip_name="sigclip_vision_patch14_384.safetensors"
- )
loadimage_440 = loadimage.load_image(image=style_image)
- clipvisionencode = NODE_CLASS_MAPPINGS["CLIPVisionEncode"]()
clipvisionencode_439 = clipvisionencode.encode(
crop="center",
clip_vision=get_value_at_index(clipvisionloader_438, 0),
image=get_value_at_index(loadimage_440, 0),
)
- stylemodelloader = NODE_CLASS_MAPPINGS["StyleModelLoader"]()
- stylemodelloader_441 = stylemodelloader.load_style_model(
- style_model_name="flux1-redux-dev.safetensors"
- )
-
- text_multiline = NODE_CLASS_MAPPINGS["Text Multiline"]()
text_multiline_454 = text_multiline.text_multiline(text="FLUX_Redux")
- emptylatentimage = NODE_CLASS_MAPPINGS["EmptyLatentImage"]()
- cr_conditioning_input_switch = NODE_CLASS_MAPPINGS[
- "CR Conditioning Input Switch"
- ]()
- cr_model_input_switch = NODE_CLASS_MAPPINGS["CR Model Input Switch"]()
- stylemodelapplyadvanced = NODE_CLASS_MAPPINGS["StyleModelApplyAdvanced"]()
- basicguider = NODE_CLASS_MAPPINGS["BasicGuider"]()
- basicscheduler = NODE_CLASS_MAPPINGS["BasicScheduler"]()
- samplercustomadvanced = NODE_CLASS_MAPPINGS["SamplerCustomAdvanced"]()
- vaedecode = NODE_CLASS_MAPPINGS["VAEDecode"]()
- saveimage = NODE_CLASS_MAPPINGS["SaveImage"]()
- imagecrop = NODE_CLASS_MAPPINGS["ImageCrop+"]()
emptylatentimage_10 = emptylatentimage.generate(
width=get_value_at_index(imageresize_72, 1),
height=get_value_at_index(imageresize_72, 2),
batch_size=1,
)
此外,为了预加载模型,我们需要使用 ComfyUI 的 load_models_gpu 函数,它将从上述预加载的模型中包含所有已加载的模型(一个很好的经验法则是,检查上述哪些加载了 *.safetensors 文件)
from comfy import model_management
#Add all the models that load a safetensors file
model_loaders = [dualcliploader_357, vaeloader_359, unetloader_358, clipvisionloader_438, stylemodelloader_441, downloadandloaddepthanythingv2model_437]
# Check which models are valid and how to best load them
valid_models = [
getattr(loader[0], 'patcher', loader[0])
for loader in model_loaders
if not isinstance(loader[0], dict) and not isinstance(getattr(loader[0], 'patcher', None), dict)
]
#Finally loads the models
model_management.load_models_gpu(valid_models)
查看 diff 以准确了解做了哪些更改
如果你不是 PRO 订阅者(如果你是,请跳过此步骤)
如果你不是 Hugging Face PRO 订阅者,你需要申请 ZeroGPU 授权。你可以轻松地转到你的 Space 的 Settings 页面并提交 ZeroGPU 授权请求。所有使用 ComfyUI 后端的 Space 的 ZeroGPU 授权请求都将获得批准 🎉。
demo 正在运行
我们通过本教程构建的 demo 已在 Hugging Face Spaces 上线。来这里体验吧:https://huggingface.co/spaces/multimodalart/flux-style-shaping
5. 结论
😮💨,就这些了!我知道这有点费功夫,但回报是可以用简单的 UI 分享你的工作流,并且所有人都能免费使用推理!如前所述,目标是在 2025 年初尽可能自动化并简化这一流程!节日快乐 🎅✨
来源:Hugging Face:Blog(RSS) · huggingface.co




