AI绘画-SDWebUI部署

Stable Diffusion是强大的图像生成模型,能够生成高质量、高分辨率的图像,并具有良好的稳定性和可控性。Stable Diffusion WebUI开源项目在模型的基础上进行封装,基于Gradio开发了可视化图形界面,为用户提供了丰富的生图工具。EAS提供了场景化部署方式,您只需配置几个参数,即可一键部署基于Stable Diffusion WebUI的服务。您可以使用该服务进行模型推理,实现基于给定文本生成相应图像的功能。本文为您介绍如何部署和调用Stable Diffusion WebUI服务,以及常见问题的解决方法。

背景信息

功能与优势

通过EAS实现Stable Diffusion WebUI的云端快速部署与应用,具体功能与优势如下:

  • 使用便捷:快捷部署,开箱即用;可根据需求动态切换GPU等底层资源。

  • 企业级功能:前后端分离改造,支持多用户对多GPU的集群调度;支持用户隔离;支持账单拆分。

  • 插件及优化:在Stable Diffusion WebUI开源版本的基础上,提供了PAI-Blade性能优化工具;提供FileBrowser插件,允许用户在桌面端上传和下载云端模型、图片;提供自研的ModelZoo插件,支持开源模型下载加速。

部署形态

Stable Diffusion WebUI服务提供了以下四种部署版本,部署流程基本相同:

  • 标准版:推荐单用户测试验证时使用。支持WebUI界面使用和API调用,只适用于部署单个实例。

  • 集群版WebUI:适合多人共同使用WebUI的场景。如果企业内设计团队需要多人协同使用,推荐选择集群版。由于集群版需要Proxy负责处理WebUI请求,因此需要额外的CPU实例。该版本优势如下:

    • 系统为每个用户分配独立的工作目录,便于管理和存储模型、输出图像或视频等文件。

    • 系统为每个用户提供独立的后端环境。当开启了多个实例时,单个用户的任务会按顺序执行,而多用户环境下的任务则在不同实例之间分配,实现高效的GPU共享。

  • API版:API版建议结合EAS异步队列使用,适用于高并发场景。基于其异步特性,系统会创建队列服务实例,因此需要分配额外的CPU实例。

  • Serverless版:目前,仅华东2(上海)、华东1(杭州)地域支持部署Serverless版服务。Serverless版服务的部署完全免费,费用仅基于生成图像所需的时间来计算,并且服务会根据您的请求量自动进行弹性伸缩。仅支持通过WebUI进行调用。

使用流程

  1. 部署服务

    根据您的具体使用场景,选择合适的部署方式,来部署标准版、API版、集群版或Serverless版的服务。

  2. 调用服务

    支持以下两种调用方式:

    • 通过WebUI页面调用服务

      使用WebUI发送服务请求,仅标准版、集群版和Serverless服务支持使用该方式。

    • 通过API调用服务

      仅标准版和API版服务支持通过API发送服务请求。其中标准版服务仅支持同步调用,而API版服务支持同步调用和异步调用。

  3. 安装插件实现增强功能

    PAI预置了非常丰富的插件,可以实现更加多样化的功能。您可以在WebUI页面的扩展页签中,查看并安装插件。

前提条件

  • 请提前准备NASOSS存储空间,用来存放模型文件和生成的图片。

  • 当您通过API调用服务时,需要配置环境变量。详情请参见Python配置访问凭证

部署服务

支持以下三种部署方式:

方式一:场景化模型部署(推荐)

支持部署标准版、API版、集群版WebUIServerless版的服务。具体操作步骤如下:

  1. 进入模型在线服务(EAS)页面。

    1. 登录PAI控制台

    2. 在左侧导航栏单击工作空间列表,在工作空间列表页面中单击待操作的工作空间名称,进入对应工作空间内。

    3. 在工作空间页面的左侧导航栏选择模型部署>模型在线服务(EAS),进入模型在线服务(EAS)页面。image

  2. 模型在线服务(EAS)页面,单击部署服务,然后在场景化模型部署区域,单击AI绘画-SDWebUI部署

  3. AI绘画-SDWebUI部署页面,配置以下关键参数。

    参数

    描述

    基本信息

    版本选择

    支持选择以下版本:

    • 标准版:推荐单用户测试验证时使用,只适用于部署单个实例。支持通过WebUI生成图像,也可通过API进行调用。

    • API:系统将自动转换服务为异步模式,适用于高并发场景。仅支持通过API进行调用。

    • 集群版WebUI:适合多用户同时在WebUI页面进行操作。仅支持通过WebUI进行调用,不提供API服务。当需要实现多人同时使用一个Stable Diffusion WebUI出图时,您可以使用集群版WebUI服务。

    • Serverless:Serverless版服务的部署完全免费,费用仅基于生成图像所需的时间来计算。仅支持通过WebUI进行使用。

    更多关于每个版本的使用场景说明,请参见背景信息

    模型配置

    单击添加按钮,进行模型配置,用来存放模型文件和推理生成的图片。支持以下两种配置类型:

    • 按对象存储OSS:使用OSS上传和下载数据更方便,能够为生成后的图像生成公网访问地址,但切换模型和保存图像的速度比NAS慢。配置OSS为已创建的OSS存储空间(Bucket)路径。

    • 按文件存储(NAS):切换模型和保存图像的速度更快。仅标准版、API版和集群版WebUI支持该配置类型。

      • NAS挂载点:选择已创建的NAS文件系统和挂载点。

      • NAS源路径:配置为/

    本文以挂载OSS为例来说明。

    资源配置

    资源配置选择

    仅标准版、API版和集群版WebUI需要进行资源配置。

    选择GPU类型,实例规格推荐使用ml.gu7i.c16m60.1-gu30(性价比最高)。

    推理加速

    支持启用推理加速功能,取值如下:

    • PAI-Blade推理加速:PAI-BladePAI推出的通用推理优化工具,对训练完成的模型进行优化,从而达到最优的推理性能。

    • 开源框架xFormers推理加速:xFormers是基于Transformer的开源加速工具,能够有效缩短图片生成时长。

    • 无加速:表示不启用推理加速功能。

    专有网络配置

    VPC

    模型配置选择按文件存储(NAS)时,系统会自动匹配与NAS所在VPC相连通的专有网络,无需进行额外的修改。

    交换机

    安全组

  4. 参数配置完成后,单击部署

方式二:自定义部署

支持部署标准版、API版和集群版WebUI服务。具体操作步骤如下:

  1. 进入模型在线服务(EAS)页面。

    1. 登录PAI控制台

    2. 在左侧导航栏单击工作空间列表,在工作空间列表页面中单击待操作的工作空间名称,进入对应工作空间内。

    3. 在工作空间页面的左侧导航栏选择模型部署>模型在线服务(EAS),进入模型在线服务(EAS)页面。image

  2. 模型在线服务(EAS)页面,单击部署服务,然后在自定义模型部署区域,单击自定义部署

  3. 新建服务页面,配置以下关键参数。

    参数

    描述

    模型服务信息

    部署方式

    • 部署标准版和集群版WebUI服务时,选择镜像部署AI-Web应用

    • 部署API版服务时,选择镜像部署服务,同时打开异步服务开关。

    镜像选择

    PAI平台镜像列表中选择stable-diffusion-webui,镜像版本选择最高版本,其中:

    • x.x-standard:表示标准版。

    • x.x-api:表示API版。

    • x.x-cluster-webui:表示集群版WebUI。

    说明
    • 由于版本迭代迅速,部署时镜像版本选择最高版本即可。

    • 当需要实现多人同时使用一个Stable Diffusion WebUI出图时,您可以选择x.x-cluster-webui版本。

    • 更多关于每个版本的使用场景说明,请参见背景信息

    填写模型配置

    单击填写模型配置,进行模型配置,用来存放模型文件和推理生成的图片。支持以下三种配置类型:

    • OSS挂载

      • OSS存储路径:将OSS路径配置为已创建的OSS Bucket路径。

      • 挂载路径:配置为/code/stable-diffusion-webui/data

    • NAS挂载

      • NAS挂载点:选择已创建的NAS文件系统和挂载点。

      • NAS源路径:配置为/

      • 挂载路径:配置为/code/stable-diffusion-webui/data

    • PAI模型挂载

      • 选择PAI模型和模型版本。

      • 挂载路径:配置为/code/stable-diffusion-webui/data

    本文以OSS挂载为例来说明。

    运行命令

    完成上述配置后,系统将自动生成相应的运行命令。

    • 填写模型配置后,您需要在运行命令中增加参数--data-dir /code/stable-diffusion-webui/data,将数据挂载到服务实例的指定路径。

    • (可选)您也可以在运行命令中增加参数--blade--xformers来开启推理加速功能,以提升出图速度。更多参数配置说明,请参见服务启动时支持配置哪些参数?

    资源部署信息

    资源配置选择

    选择GPU类型,实例规格推荐使用ml.gu7i.c16m60.1-gu30(性价比最高)。

    专有网络配置

    VPC

    模型配置选择按文件存储(NAS)时,系统会自动匹配与NAS所在VPC相连通的专有网络,无需进行额外的修改。

    交换机

    安全组

  4. 参数配置完成后,单击部署

方式三:JSON独立部署

您可以使用JSON独立部署方式,来部署Stable Diffusion WebUI服务,以下以标准版和API版为例,具体操作步骤如下:

  1. 进入模型在线服务页面。

    1. 登录PAI控制台

    2. 在左侧导航栏单击工作空间列表,在工作空间列表页面中单击待操作的工作空间名称,进入对应工作空间内。

    3. 在工作空间页面的左侧导航栏选择模型部署>模型在线服务(EAS),进入模型在线服务(EAS)页面。image

  2. 模型在线服务(EAS)页面,单击部署服务,在自定义模型部署区域,单击JSON独立部署

  3. JSON独立部署页面编辑框中,配置以下JSON格式的内容。

    部署标准版服务

    {
        "metadata": {
            "instance": 1,
            "name": "sd_v32",
            "enable_webservice": true
        },
        "containers": [
            {
                "image": "eas-registry-vpc.<region>.cr.aliyuncs.com/pai-eas/stable-diffusion-webui:4.2",
                "script": "./webui.sh --listen --port 8000 --skip-version-check --no-hashing --no-download-sd-model --skip-prepare-environment --api --filebrowser --data-dir=/code/stable-diffusion-webui/data",
                "port": 8000
            }
        ],
        "cloud": {
            "computing": {
                "instance_type": "ml.gu7i.c16m60.1-gu30",
                "instances": null
            },
            "networking": {
                "vpc_id": "vpc-t4nmd6nebhlwwexk2****",
                "vswitch_id": "vsw-t4nfue2s10q2i0ae3****",
                "security_group_id": "sg-t4n85ksesuiq3wez****"
            }
        },
        "storage": [
            {
                "oss": {
                    "path": "oss://examplebucket/data-oss",
                    "readOnly": false
                },
                "properties": {
                    "resource_type": "model"
                },
                "mount_path": "/code/stable-diffusion-webui/data"
            },
            {
                "nfs": {
                    "path": "/",
                    "server": "726434****-aws0.ap-southeast-1.nas.aliyuncs.com"
                },
                "properties": {
                    "resource_type": "model"
                },
                "mount_path": "/code/stable-diffusion-webui/data"
            }
        ]
    } 

    其中关键参数说明如下:

    参数

    是否必选

    描述

    metadata.name

    自定义模型服务名称,同地域唯一。

    containers.image

    其中<region>需要替换为当前地域ID,例如华东2(上海)为cn-shanghai。关于如何查询地域ID,请参见地域和可用区

    storage

    支持以下两种挂载方式,任意选择一种即可:

    • OSS:使用OSS上传和下载数据更方便,能够为生成后的图像生成公网访问地址,但切换模型和保存图像的速度比NAS慢。您需要将storage.oss.path配置为已创建的OSS存储空间路径。

    • NAS:使用NAS挂载方式,切换模型和保存图像的速度更快。您需要将storage.nfs.server配置为已创建的NAS文件系统。

    本文以挂载OSS为例来说明。

    cloud.networking

    storage使用NAS挂载时,您需要配置专有网络,包括vpc_id(专有网络ID)、vswitch_id(交换机ID)和security_group_id(安全组ID),且配置的专有网络需要与通用型NAS文件系统保持一致。

    部署API版服务

    {
        "metadata": {
            "name": "sd_async",
            "instance": 1,
            "rpc.worker_threads": 1,
            "type": "Async"
        },
        "cloud": {
            "computing": {
                "instance_type": "ml.gu7i.c16m60.1-gu30",
                "instances": null
            },
            "networking": {
                "vpc_id": "vpc-bp1t2wukzskw9139n****",
                "vswitch_id": "vsw-bp12utkudylvp4c70****",
                "security_group_id": "sg-bp11nqxfd0iq6v5g****"
            }
        },
        "queue": {
            "cpu": 1,
            "max_delivery": 1,
            "memory": 4000,
            "resource": ""
        },
        "storage": [
            {
                "oss": {
                    "path": "oss://examplebucket/aohai-singapore/",
                    "readOnly": false
                },
                "properties": {
                    "resource_type": "model"
                },
                "mount_path": "/code/stable-diffusion-webui/data"
            },
            {
                "nfs": {
                    "path": "/",
                    "server": "0c9624****-fgh60.cn-hangzhou.nas.aliyuncs.com"
                },
                "properties": {
                    "resource_type": "model"
                },
                "mount_path": "/code/stable-diffusion-webui/data"
            }
        ],
        "containers": [
            {
                "image": "eas-registry-vpc.<region>.cr.aliyuncs.com/pai-eas/stable-diffusion-webui:4.2",
                "script": "./webui.sh --listen --port 8000 --skip-version-check --no-hashing --no-download-sd-model --skip-prepare-environment --api-log --time-log --nowebui --data-dir=/code/stable-diffusion-webui/data",
                "port": 8000
            }
        ]
    } 

    相较于标准版服务的配置,以下是API版服务的配置变更,其他参数配置与标准版服务相同。

    参数

    描述

    删除以下参数:

    metadata.enable_webservice

    删除该参数,表示不开启webserver。

    containers.script

    删除containers.script中配置的--filebrowser,加快服务启动速度。

    新增以下参数:

    metadata.type

    配置为Async,表示打开异步服务。

    metadata.rpc.worker_threads

    配置为1,单个实例只允许并发处理一个请求。

    queue.max_delivery

    配置为1,消息处理错误后不允许重试。

    containers.script

    containers.script配置中新增--nowebui(加快启动速度)和--time-log(记录接口响应时间)。

    更多参数配置说明,请参见部署标准版服务

  4. 单击部署

调用服务

通过WebUI页面调用服务

通过WebUI,您可以调用标准版、集群版WebUIServerless版的服务。具体操作步骤如下:

  1. 服务部署成功后,单击目标服务的服务方式列下的查看Web应用

  2. 进行模型推理验证。

    Stable Diffusion WebUI页面文生图页签中,输入正向提示词Prompt,例如cute dog,然后单击生成,即可完成AI绘图,效果图如下:

    image

通过API调用服务

标准版和API版服务支持API调用。API调用支持同步调用和异步调用两种方式,其中标准版服务仅支持同步调用,API版服务支持同步调用和异步调用方式。

  • 同步调用:即客户端发送一个请求,同步等待结果返回。

  • 异步调用:即客户端使用EAS的队列服务向输入队列发送请求,并通过订阅的方式从输出队列查询结果。

调用同步服务

标准版和API版服务部署成功后,您可以参照以下操作步骤发送同步接口请求。

  1. 查询调用信息。

    1. 服务部署成功后,单击服务名称,进入服务详情页面。

    2. 基本信息区域中,单击查看调用信息

    3. 调用信息对话框中,查询服务访问地址和Token。

      • 如果该服务是API版服务,您需要在同步调用页签的公网地址调用页签中,查询服务访问地址和Token。image

      • 如果该服务是标准版服务,您需要在公网地址调用页签中,查询服务访问地址和Token。image

  2. 使用以下几种方式发送同步接口请求。

    使用curl命令发送服务请求

    示例如下:

    curl --location --request POST '<service_url>/sdapi/v1/txt2img' \
    --header 'Authorization: <token>' \
    --header 'Content-Type: application/json' \
    --data-raw '{
      "prompt":"cut dog ",
      "steps":20
    }'

    其中:

    • <service_url>:替换为步骤1中查询到的服务访问地址,您需要将访问地址末尾的/删除。

    • <token>:替换为步骤1中查询到的服务Token。

    命令执行成功后,系统会返回图像的Base64位编码。

    使用Python发送服务请求

    参考API发送服务请求。

    • 示例1(推荐):建议您为EAS服务挂载OSS来保存生成后的图像。以下示例在请求体中设置保存地址为OSS挂载路径,实现了将图像直接保存至OSS,并且使用了oss2 SDK获取OSS中的图像下载到本地。

      import requests
      import oss2
      from oss2.credentials import EnvironmentVariableCredentialsProvider
      
      # 第一步:发送请求,生成的图像会保存至OSS。
      url = "<service_url>"
      
      # 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录RAM控制台创建RAM账号。
      auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
      
      # Endpoint以杭州为例,其它Region请按实际情况填写。
      bucket = oss2.Bucket(auth, '<endpoint>', '<examplebucket>')
      
      payload = {
          "alwayson_scripts": {
              "sd_model_checkpoint": "deliberate_v2.safetensors",
              "save_dir": "/code/stable-diffusion-webui/data/outputs"
          },
          "steps": 30,
          "prompt": "girls",
          "batch_size": 1,
          "n_iter": 2,
          "width": 576,
          "height": 576,
          "negative_prompt": "ugly, out of frame"
      }
      
      session = requests.session()
      session.headers.update({"Authorization": "<token>"})
      
      response = session.post(url=f'{url}/sdapi/v1/txt2img', json=payload)
      if response.status_code != 200:
          raise Exception(response.content)
      
      data = response.json()
      
      
      # 第二步:获取OSS中的图像下载到本地。
      
      # 对应部署EAS服务时,storage挂载OSS文件夹对应的mount_path。
      mount_path = "/code/stable-diffusion-webui/data"
      
      # 对应部署EAS服务时,storage中选择的OSS地址。
      oss_url = "oss://examplebucket/data-oss"
      
      for idx, img_path in enumerate(data['parameters']['image_url'].split(',')):
          # 获取生成的图像在OSS中的实际地址。
          img_oss_path = img_path.replace(mount_path, oss_url)
          print(idx, img_oss_path, url)
      
          # 下载OSS文件到本地文件。其中<examplebucket>需要替换为已创建的OSS存储空间(Bucket)名称。
          bucket.get_object_to_file(img_oss_path[len("oss://examplebucket/"):], f'output-{idx}.png')

      其中关键配置说明如下:

      配置

      描述

      url

      <service_url>替换为步骤1中查询到的服务访问地址。您需要将访问地址末尾的/删除。

      bucket

      其中:

      • <endpoint>表示配置的OSSEndpoint。例如:华东2(上海)地域的Endpointhttp://oss-cn-shanghai.aliyuncs.com。如果您在其他地域部署的服务,需要根据实际情况进行配置。详情请参见OSS地域和访问域名

      • <examplebucket>需要替换为已创建的OSS存储空间(Bucket)名称。

      <token>

      替换为步骤1中查询到的服务Token。

      mount_path

      配置为部署服务时配置的OSS挂载路径。

      oss_url

      配置为部署服务时配置的OSS存储路径。

      代码执行成功后,系统返回如下结果。您可以前往OSS控制台,在部署服务时挂载存储的outputs目录中查看已生成的图片。

      0 /code/stable-diffusion-webui/data/outputs/txt2img-grids/2024-06-26/grid-093546-9ad3f23e-a5c8-499e-8f0b-6effa75bd04f.png oss://examplebucket/data-oss/outputs/txt2img-grids/2024-06-26/grid-093546-9ad3f23e-a5c8-499e-8f0b-6effa75bd04f.png
      1 /code/stable-diffusion-webui/data/outputs/txt2img-images/2024-06-26/093536-ab4c6ab8-880d-4de6-91d5-343f8d97ea3c-3257304074.png oss://examplebucket/data-oss/outputs/txt2img-images/2024-06-26/093536-ab4c6ab8-880d-4de6-91d5-343f8d97ea3c-3257304074.png
      2 /code/stable-diffusion-webui/data/outputs/txt2img-images/2024-06-26/093545-6e6370d7-d41e-4105-960a-b4739af30c0d-3257304075.png oss://examplebucket/data-oss/outputs/txt2img-images/2024-06-26/093545-6e6370d7-d41e-4105-960a-b4739af30c0d-3257304075.png
    • 示例2:保存图像至本地路径。执行以下Python代码,会返回图像的Base64位编码,并将图像文件保存至本地目录。

      import requests
      import io
      import base64
      from PIL import Image, PngImagePlugin
      
      url = "<service_url>"
      
      payload = {
          "prompt": "puppy dog",
          "steps": 20,
          "n_iter": 2
      }
      
      session = requests.session()
      session.headers.update({"Authorization": "<token>"})
      
      
      response = session.post(url=f'{url}/sdapi/v1/txt2img', json=payload)
      if response.status_code != 200:
          raise Exception(response.content)
      
      data = response.json()
      
      # 同步接口可直接返回图片的base64,但推荐使用返回图片地址。
      for idx, im in enumerate(data['images']):
          image = Image.open(io.BytesIO(base64.b64decode(im.split(",", 1)[0])))
      
          png_payload = {
              "image": "data:image/png;base64," + im
          }
          resp = session.post(url=f'{url}/sdapi/v1/png-info', json=png_payload)
      
          pnginfo = PngImagePlugin.PngInfo()
          pnginfo.add_text("parameters", resp.json().get("info"))
          image.save(f'output-{idx}.png', pnginfo=pnginfo)
      

      其中:

      • <service_url>:替换为步骤1中查询到的服务访问地址,您需要将访问地址末尾的/删除。

      • <token>:替换为步骤1中查询到的服务Token。

    此外,您还可以在请求数据中使用LoRAControlnet数据格式,以实现特定的功能。

    请求数据中使用LoRA模型配置

    发送服务请求时,您可以直接在请求体上加入<lora:yaeMikoRealistic_Genshin:1000>来增加Lora。更多详细内容,请参见Lora

    请求体配置示例如下:

    {
      "prompt":"girls <lora:yaeMikoRealistic_Genshin:1>",
      "steps":20,
      "save_images":true
    }

    请求数据中使用ControlNet数据格式

    API请求数据中使用Controlnet数据格式可以方便地对图像进行一些常见的变换操作,比如使图像保持水平或垂直等。具体配置方法,请参见txt2img使用controlnet的数据格式

调用异步服务

API版服务部署成功后,您可以向该服务发送异步接口请求,即客户端不再同步等待结果,通过订阅的方式在请求计算完成后等待服务端的结果推送。具体操作步骤如下:

  1. 查询调用信息。

    服务部署成功后,单击服务方式列下的调用信息,在异步调用页签的公网输入请求地址页签中,查询服务访问地址和Token。image

  2. 客户端通过异步接口向服务端发送请求,支持使用Python SDKJava SDK两种方式。

    重要
    • 异步队列对输入请求和输出结果的大小都有限制,通常不建议超过8 KB。因此,在发送请求时,需要满足以下两个条件:

      • 如果请求数据中包含图片,建议使用URL来传递图片信息。Stable Diffusion WebUI内部会自动下载并解析这些图片数据。

      • 为了确保返回结果中没有原始图片数据,建议您使用save_dir来指定生成图片的保存路径。具体操作,请参见API接口额外支持配置的参数有哪些?

    • 默认情况下,EAS无法连接互联网。如果您使用image_link参数配置的图片链接是互联网图片地址,为了能够正常访问这些图片,您需要参考配置网络连通进行公网连接配置。

    方式一:使用Python SDK

    示例代码如下:

    import requests
    
    url = "<service_url>"
    session = requests.session()
    session.headers.update({"Authorization": "<token>"})
    
    prompts = ["cute dog", "cute cat", "cute girl"]
    
    for i in range(5):
        p = prompts[i % len(prompts)]
        payload = {
            "prompt": p,
            "steps": 20,
            "alwayson_scripts": {
                "save_dir": "/code/stable-diffusion-webui/data-oss/outputs/txt2img"
            },
        }
        response = session.post(url=f'{url}/sdapi/v1/txt2img?task_id=txt2img_{i}', json=payload)
        if response.status_code != 200:
            exit(f"send request error:{response.content}")
        else:
            print(f"send {p} success, index is {response.content}")
    
    
    for i in range(5):
        p = prompts[i % len(prompts)]
        payload = {
            "prompt": p,
            "steps": 20,
            "alwayson_scripts": {
                "save_dir": "/code/stable-diffusion-webui/data-oss/outputs/img2img",
                "image_link": "https://eas-cache-cn-hangzhou.oss-cn-hangzhou-internal.aliyuncs.com/stable-diffusion-cache/tests/boy.png",
            },
        }
        response = session.post(url=f'{url}/sdapi/v1/img2img?task_id=img2img_{i}', json=payload)
        if response.status_code != 200:
            exit(f"send request error:{response.content}")
        else:
            print(f"send {p} success, index is {response.content}")
    

    其中:

    • <service_url>:替换为步骤1中查询到的服务访问地址。您需要将访问地址末尾的/删除。

    • <token>:替换为步骤1中查询到的服务Token。

    说明
    • 可以支持WebUI服务的所有POST接口,按照需求请求对应路径。

    • 如果您需要在该服务中透传业务属性,可以使用url参数的方式指定属性标签。例如,您可以在responseurl参数中添加参数?task_id=task_abc来指定标签为task_id,并且该信息会在服务的输出结果中的tags字段中体现。

    代码执行成功后,系统输出如下结果。您的结果以实际为准。image.png

    方式二:使用Java SDK

    使用Java编写客户端代码时,需要使用Maven管理项目。因此,您必须在pom.xml文件中添加客户端所需的依赖包。具体操作,请参见Java SDK使用说明

    示例代码如下。

    import com.aliyun.openservices.eas.predict.http.HttpConfig;
    import com.aliyun.openservices.eas.predict.http.QueueClient;
    import com.aliyun.openservices.eas.predict.queue_client.QueueUser;
    import org.apache.commons.lang3.tuple.Pair;
    
    import java.util.HashMap;
    
    public class SDWebuiAsyncPutTest {
        public static void main(String[] args) throws Exception {
            // 创建队列服务客户端。
            String queueEndpoint = "http://166233998075****.cn-hangzhou.pai-eas.aliyuncs.com";
            String queueToken = "xxxxx==";
            // 输入队列为服务名+自定义请求path。
            String inputQueueName = "<service_name>/sdapi/v1/txt2img";
    
            // 输入队列,往输入队列添加数据,推理服务会自动从输入队列中读取请求数据。
            QueueClient inputQueue =
                new QueueClient(queueEndpoint, inputQueueName, queueToken, new HttpConfig(), new QueueUser());
            // 清除队列数据!!! 请谨慎使用。
            // input_queue.clear();
    
            // 往输入队列添加数据。
            int count = 5;
            for (int i = 0; i < count; ++i) {
                // 请求数据。
                String data = "{\n" +
                    "    \"prompt\": \"cute dog\", \n" +
                    "    \"steps\":20,\n" +
                    "    \"alwayson_scripts\":{\n" +
                    "        \"save_dir\":\"/code/stable-diffusion-webui/data-oss/outputs/txt2img\"\n" +
                    "    }\n" +
                    "  }";
                // 自定义tag。
                HashMap<String, String> map = new HashMap<String, String>(1);
                map.put("task_id", "txt2img_" + i);
                Pair<Long, String> entry = inputQueue.put(data.getBytes(), map);
    
                System.out.println(String.format("send success, index is %d, request_id is %s", entry.getKey(), entry.getValue()));
                // 队列服务支持多优先级队列,可通过put函数设置数据优先级,默认优先级为0, 高优先数据可设置优先级为1。
                //  inputQueue.put(data.getBytes(), 0L, null);
            }
            // 关闭客户端。
            inputQueue.shutdown();
    
    
            inputQueueName = "<service_name>/sdapi/v1/img2img";
            inputQueue =
                new QueueClient(queueEndpoint, inputQueueName, queueToken, new HttpConfig(), new QueueUser());
            for (int i = 0; i < count; ++i) {
                // 请求数据。
                String data = "{\n" +
                    "    \"prompt\": \"cute dog\", \n" +
                    "    \"steps\":20,\n" +
                    "    \"alwayson_scripts\":{\n" +
                    "        \"save_dir\":\"/code/stable-diffusion-webui/data-oss/outputs/img2img\",\n" +
                    "        \"image_link\":\"https://eas-cache-cn-hangzhou.oss-cn-hangzhou-internal.aliyuncs.com/stable-diffusion-cache/tests/boy.png\"\n" +
                    "    }\n" +
                    "  }";
                HashMap<String, String> map = new HashMap<String, String>(1);
                map.put("task_id", "img2img_" + i);
                Pair<Long, String> entry = inputQueue.put(data.getBytes(), map);
    
                System.out.println(String.format("send success, index is %d, requestId is %s", entry.getKey(), entry.getValue()));
            }
    
            // 关闭客户端。
            inputQueue.shutdown();
        }
    }

    其中:

    • queueEndpoint:配置为步骤1中获取的服务访问地址。请参考示例代码进行相应的配置。

    • queueToken:配置为步骤1中获取的服务Token信息。

    • <service_name>:替换为已部署的异步服务名称。

    说明

    如果您需要在服务中透传业务属性,可以在put函数中设置tag参数。在示例中,您可以参考自定义tag的用法。这些信息会在输出结果的tags属性中体现。

    代码执行成功后,系统输出如下结果。您的结果以实际为准。

    send success, index is 21, request_id is 05ca7786-c24e-4645-8538-83d235e791fe
    send success, index is 22, request_id is 639b257a-7902-448d-afd5-f2641ab77025
    send success, index is 23, request_id is d6b2e127-eba3-4414-8e6c-c3690e0a487c
    send success, index is 24, request_id is 8becf191-962d-4177-8a11-7e4a450e36a7
    send success, index is 25, request_id is 862b2d8e-5499-4476-b3a5-943d18614fc5
    send success, index is 26, requestId is 9774a4ff-f4c8-40b7-ba43-0b1c1d3241b0
    send success, index is 27, requestId is fa536d7a-7799-43f1-947f-71973bf7b221
    send success, index is 28, requestId is e69bdd32-5c7b-4c8f-ba3e-e69d2054bf65
    send success, index is 29, requestId is c138bd8f-be45-4a47-a330-745fd1569534
    send success, index is 30, requestId is c583d4f8-8558-4c8d-95f7-9c3981494007
    
    Process finished with exit code 0

  3. 异步订阅结果。

    客户端采用订阅方式,一旦服务端完成相关请求的处理,便会自动推送结果至客户端,实现高效异步通信。支持使用PyThon SDKJava SDK两种方式异步订阅结果。

    方式一:使用Python SDK

    示例代码如下:

    import json
    import oss2
    
    from oss2.credentials import EnvironmentVariableCredentialsProvider
    from eas_prediction import QueueClient
    
    sink_queue = QueueClient('139699392458****.cn-hangzhou.pai-eas.aliyuncs.com', 'sd_async/sink')
    sink_queue.set_token('<token>')
    sink_queue.init()
    
    mount_path = "/code/stable-diffusion-webui/data-oss"
    oss_url = "oss://<examplebucket>/aohai-singapore"
    # 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录RAM控制台创建RAM账号。
    auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
    # Endpoint以杭州为例,其它Region请按实际情况填写。
    bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<examplebucket>')
    
    
    watcher = sink_queue.watch(0, 5, auto_commit=False)
    for x in watcher.run():
        if 'task_id' in x.tags:
            print('index {} task_id is {}'.format(x.index, x.tags['task_id']))
        print(f'index {x.index} data is {x.data}')
        sink_queue.commit(x.index)
        try:
            data = json.loads(x.data.decode('utf-8'))
            for idx, path in enumerate(data['parameters']['image_url'].split(',')):
                url = path.replace(mount_path, oss_url)
                # 下载OSS文件到本地。
                bucket.get_object_to_file(url[len("oss://<examplebucket>/"):], f'{x.index}-output-{idx}.png')
                print(f'save {url} to {x.index}-output-{idx}.png')
        except Exception as e:
            print(f'index {x.index} process data error {e}')
    

    其中关键配置说明如下:

    配置

    描述

    sink_queue

    • 参考示例代码格式,将139699392458****.cn-hangzhou.pai-eas.aliyuncs.com替换为上述步骤已获取的服务访问地址中的服务Endpoint。

    • 参考示例代码格式,将sd_async替换为已部署的异步服务名称。

    <token>

    需要配置为步骤1中获取的服务Token信息。

    oss_url

    替换为部署服务时配置的OSS存储路径。

    bucket

    其中:

    • http://oss-cn-hangzhou.aliyuncs.com表示以华东1(杭州)地域为例,配置的OSSEndpoint。如果您在其他地域部署的服务,需要根据实际情况进行配置。详情请参见OSS地域和访问域名

    • <examplebucket>需要替换为已创建的OSS存储空间(Bucket)名称。

    说明
    • 需要主动进行commit操作,也可以设置auto_commit=True来自动进行commit操作。

    • 如果consumer不再消费数据,需要及时关闭以释放资源。

    • 您也可以使用curl命令或者调用同步接口来获取订阅接口,详情请参见部署异步推理服务

    客户端通过watcher.run()方法持续侦听服务端的结果。如果服务端一直没有结果,客户端将持续等待,如果服务端有结果返回,则打印输出结果。示例结果如下,您的结果以实际为准。您可以前往OSS控制台,在部署服务时配置的OSS存储路径中查看已生成的图片。

    index 1 task_id is txt2img_0
    index 1 data is b'{"images":[],"parameters":{"id_task":null,"status":0,"image_url":"/code/stable-diffusion-webui/data/outputs/txt2img/txt2img-images/2024-07-01/075825-a2abd45f-3c33-43f2-96fb-****50329671-1214613912.png","seed":"1214613912","error_msg":"","image_mask_url":""},"info":"{\\"hostname\\": \\"***-8aff4771-5c86c8d656-hvdb8\\"}"}'
    save oss://examplebucket/xx/outputs/txt2img/txt2img-images/2024-07-01/075825-a2abd45f-3c33-43f2-96fb-****50329671-1214613912.png to 1-output-0.png
    index 2 task_id is txt2img_1
    index 2 data is b'{"images":[],"parameters":{"id_task":null,"status":0,"image_url":"/code/stable-diffusion-webui/data/outputs/txt2img/txt2img-images/2024-07-01/075827-c61af78c-25f2-47cc-9811-****aa51f5e4-1934284737.png","seed":"1934284737","error_msg":"","image_mask_url":""},"info":"{\\"hostname\\": \\"***-8aff4771-5c86c8d656-hvdb8\\"}"}'
    save oss://examplebucket/xx/outputs/txt2img/txt2img-images/2024-07-01/075827-c61af78c-25f2-47cc-9811-****aa51f5e4-1934284737.png to 2-output-0.png
    index 3 task_id is txt2img_2
    index 3 data is b'{"images":[],"parameters":{"id_task":null,"status":0,"image_url":"/code/stable-diffusion-webui/data/outputs/txt2img/txt2img-images/2024-07-01/075829-1add1f5c-5c61-4f43-9c2e-****9d987dfa-3332597009.png","seed":"3332597009","error_msg":"","image_mask_url":""},"info":"{\\"hostname\\": \\"***-8aff4771-5c86c8d656-hvdb8\\"}"}'
    save oss://examplebucket/xx/outputs/txt2img/txt2img-images/2024-07-01/075829-1add1f5c-5c61-4f43-9c2e-****9d987dfa-3332597009.png to 3-output-0.png
    index 4 task_id is txt2img_3
    index 4 data is b'{"images":[],"parameters":{"id_task":null,"status":0,"image_url":"/code/stable-diffusion-webui/data/outputs/txt2img/txt2img-images/2024-07-01/075832-2674c2d0-8a93-4cb5-9ff4-****46cec1aa-1250290207.png","seed":"1250290207","error_msg":"","image_mask_url":""},"info":"{\\"hostname\\": \\"***-8aff4771-5c86c8d656-hvdb8\\"}"}'
    save oss://examplebucket/xx/outputs/txt2img/txt2img-images/2024-07-01/075832-2674c2d0-8a93-4cb5-9ff4-****46cec1aa-1250290207.png to 4-output-0.png
    index 5 task_id is txt2img_4
    index 5 data is b'{"images":[],"parameters":{"id_task":null,"status":0,"image_url":"/code/stable-diffusion-webui/data/outputs/txt2img/txt2img-images/2024-07-01/075834-8bb15707-ff0d-4dd7-b2da-****27717028-1181680579.png","seed":"1181680579","error_msg":"","image_mask_url":""},"info":"{\\"hostname\\": \\"***-8aff4771-5c86c8d656-hvdb8\\"}"}'
    save oss://examplebucket/xx/outputs/txt2img/txt2img-images/2024-07-01/075834-8bb15707-ff0d-4dd7-b2da-****27717028-1181680579.png to 5-output-0.png

    方式二:使用Java SDK

    示例代码如下:

    import com.aliyun.openservices.eas.predict.http.HttpConfig;
    import com.aliyun.openservices.eas.predict.http.QueueClient;
    import com.aliyun.openservices.eas.predict.queue_client.DataFrame;
    import com.aliyun.openservices.eas.predict.queue_client.QueueUser;
    import com.aliyun.openservices.eas.predict.queue_client.WebSocketWatcher;
    
    public class SDWebuiAsyncWatchTest {
        public static void main(String[] args) throws Exception {
            // 创建队列服务客户端。
            String queueEndpoint = "http://166233998075****.cn-hangzhou.pai-eas.aliyuncs.com";
            String queueToken = "xxxxx==";
            // 输出队列名为 服务名+"/sink"。
            String sinkQueueName = "<service_name>/sink";
    
            // 输出队列,推理服务处理输入数据后会将结果写入输出队列。
            QueueClient sinkQueue =
                new QueueClient(queueEndpoint, sinkQueueName, queueToken, new HttpConfig(), new QueueUser());
    
            // 清除队列数据!!! 请谨慎使用。
            //  sinkQueue.clear();
    
            // 订阅队列,获取队列数据。
            WebSocketWatcher watcher = sinkQueue.watch(0L, 5L, false, false, null);
            try {
                while (true) {
                    DataFrame df = watcher.getDataFrame();
                    if (df.getTags().containsKey("task_id")) {
                        System.out.println(String.format("task_id = %s", df.getTags().get("task_id")));
                    }
                    System.out.println(String.format("index = %d, data = %s, requestId = %s", df.getIndex(), new String(df.getData()), df.getTags().get("requestId")));
                    sinkQueue.commit(df.getIndex());
                }
            } catch (Exception e) {
                System.out.println("watch error:" + e.getMessage());
                e.printStackTrace();
                watcher.close();
            }
    
            // 关闭客户端。
            sinkQueue.shutdown();
        }
    }

    其中:

    • queueEndpoint:配置为步骤1中获取的服务访问地址。请参考示例代码进行相应的配置。

    • queueToken:配置为步骤1中获取的服务Token信息。

    • <service_name>:替换为已部署的异步服务名称。

    说明
    • 需要主动进行commit操作,也可以设置auto_commit=True来自动进行commit操作。

    • 如果consumer不再消费数据,需要及时关闭以释放资源。

    • 您也可以使用curl命令或者调用同步接口来获取订阅接口,详情请参见部署异步推理服务

    客户端通过watcher.getDataFrame()方法持续侦听服务端的结果。如果服务端一直没有结果,客户端将持续等待,如果服务端有结果返回,则打印输出结果。示例结果如下,您的结果以实际为准。您可以前往OSS控制台对应的路径下查看已生成的图片。

    2023-08-04 16:17:31,497 INFO [com.aliyun.openservices.eas.predict.queue_client.WebSocketWatcher] - WebSocketClient Successfully Connects to Server: 1396993924585947.cn-hangzhou.pai-eas.aliyuncs.com/116.62.XX.XX:80
    task_id = txt2img_0
    index = 21, data = {"images":[],"parameters":{"id_task":null,"status":0,"image_url":"/code/stable-diffusion-webui/data-oss/outputs/txt2img/txt2img-images/2023-08-04/54363a9d-24a5-41b5-b038-2257d43b8e79-412510031.png","seed":"412510031","error_msg":"","total_time":2.5351321697235107},"info":""}, requestId = 05ca7786-c24e-4645-8538-83d235e791fe
    task_id = txt2img_1
    index = 22, data = {"images":[],"parameters":{"id_task":null,"status":0,"image_url":"/code/stable-diffusion-webui/data-oss/outputs/txt2img/txt2img-images/2023-08-04/0c646dda-4a53-43f4-97fd-1f507599f6ae-2287341785.png","seed":"2287341785","error_msg":"","total_time":2.6269655227661133},"info":""}, requestId = 639b257a-7902-448d-afd5-f2641ab77025
    task_id = txt2img_2
    index = 23, data = {"images":[],"parameters":{"id_task":null,"status":0,"image_url":"/code/stable-diffusion-webui/data-oss/outputs/txt2img/txt2img-images/2023-08-04/4d542f25-b9cc-4548-9db2-5addd0366d32-1158414078.png","seed":"1158414078","error_msg":"","total_time":2.6604185104370117},"info":""}, requestId = d6b2e127-eba3-4414-8e6c-c3690e0a487c
    task_id = txt2img_3

    在异步发送请求并订阅其结果后,您可以利用search()方法主动查询该请求的处理状态,以确定是否已完成。详情请参见Python SDK使用说明Java SDK使用说明

EAS基于原生Stable Diffusion WebUI接口支持了一些新特性,您可以在请求数据中添加一些可选参数用于实现更加丰富的功能或定制化需求。具体操作,请参见API接口额外支持配置的参数有哪些?

安装插件实现增强功能

您可以为Stable Diffusion WebUI配置插件,以实现更加多样化的功能。PAI预置了丰富的插件,例如PAI自主研发的BeautifulPrompt插件,用来实验Prompt的扩写和美化。下文将以BeautifulPrompt插件为例,为您介绍插件的安装和使用方法。

安装插件

您可以在WebUI页面的扩展页签中,查看并安装插件。具体操作步骤如下:

  1. 在服务列表中,单击目标服务的服务方式列下的查看Web应用,来启动WebUI。image

  2. WebUI页面中的扩展页签下,检查是否已选中BeautifulPrompt。如果未选中,您需要选中该插件,并单击应用更改并重载前端,来重新加载BeautifulPrompt插件。image

    在安装插件时,WebUI页面将会自动重启,待重新加载完成后即可进行推理验证。

使用插件进行推理验证

  1. 切换到BeautifulPrompt页签,在文本框中输入一个比较简单的Prompt,然后单击生成,即可生成更详细的Prompt。image

    PAI提供了多个Prompt生成模型,每个模型生成的Prompt略有不同。其中:

    • pai-bloom-1b1-text2prompt-sd-v2:擅长生成复杂场景下的Prompt。

    • pai-bloom-1b1-text2prompt-sd:生成描述单个物体的Prompt。

    您可以根据场景需要选择合适的模型来生成Prompt。image

  2. 选择需要使用的Prompt,单击Prompt右侧的to txt2img

    页面自动跳转至文生图页签,并自动填充了提示词(Prompt)区域。image

  3. 单击生成,即可在WebUI页面右侧生成图片。image

    与不使用BeautifulPrompt插件相比,使用BeautifulPrompt插件可以提升生成图像的美观度,并且帮助您补充更多细节。其他场景使用BeautifulPrompt插件前后效果对比如下:

    输入Prompt

    不使用BeautifulPrompt的效果

    使用BeautifulPrompt的效果

    a cat

    image.png

    image.png

    a giant tiger

    image.png

    image.png

常见问题

如何挂载自己的模型及输出目录等内容

服务部署成功后,系统会自动在已挂载的OSSNAS存储空间中创建以下目录结构:image

其中:

  • models:该目录用来存放模型文件。

  • 发起推理请求后,系统将按照API代码中预设的配置,自动将结果文件输出至该目录中。

您可以将从开源社区下载的模型或自己训练得到的LoRAStable Diffusion等模型存放于上述指定目录中,以便加载使用新的模型。具体操作步骤如下:

  1. 请将模型文件上传至挂载存储的models目录下的相应子目录中,具体操作,请参见步骤二:上传文件

  2. 模型在线服务(EAS)页面,单击目标服务操作列下的image>重启服务,服务重启成功后,即可生效。

  3. Stable Diffusion WebUI页面切换模型,进行模型推理验证。

    image

服务长时间卡住怎么办?

  • 您可以先尝试重新打开Stable Diffusion WebUI界面或重启EAS服务来解决:

    • 单击目标服务服务方式列下的查看Web应用,重新打开Stable Diffusion WebUI。

    • 单击目标服务操作列下的image>重启服务,重启EAS服务。

  • 如果重启后长时间无法解决,则大概率是因为服务需要从外网下载模型或插件等内容导致。EAS默认不开公网,镜像可以离线启动,挂载模型也无需网络。但部分插件的使用,需要依赖从互联网下载相关内容。此时推荐您根据日志,找到模型或插件的下载路径,手动下载模型并上传到OSS进行挂载,详情请参见如何挂载自己的模型及输出目录等内容。如果仍需要连接互联网,请参见配置网络连通进行公网连接配置。

如何将WebUI页面的默认语言切换为英文?

  1. Stable Diffusion WebUI页面单击设置

  2. 在左侧导航栏单击用户界面,在右侧页面本地化区域,选择

  3. Stable Diffusion WebUI页面上方,单击保存设置,保存成功后单击重载前端

    重新刷新WebUI页面,即可切换为英文。

如何更方便地管理自己的文件系统?

在部署标准版、集群版WebUI服务时,系统已默认在运行命令中增加了--filebrowser参数,您可以直接通过WebUI界面管理您的文件系统。具体操作步骤如下:

  1. 服务部署完成后,单击服务方式列下的查看Web应用

  2. Stable Diffusion WebUI页面,单击FileBrowser页签。您可以直接查看文件系统,或进行上传、下载操作。

    image

服务启动时支持配置哪些参数?

  • 公共参数

    公共参数

    功能说明

    使用建议

    --blade

    启用PAI-blade加速,提升出图速度。

    建议开启。

    --filebrowser

    支持您自主上传、下载模型或图片的插件。

    默认启用。

    --data-dir /code/stable-diffusion-webui/data-oss

    持久化存储挂载使用的路径。

    挂载持久化存储时使用,默认起始路径为/code/stable-diffusion-webui/,也可以使用相对路径。

    --api

    WebUIAPI调用模式。

    默认启用。

    --enable-nsfw-censor

    默认关闭。如果您有安全合规需求,则可以选择开启鉴黄过滤功能。

    根据业务需要进行调整。

    --always-hide-tabs

    指定部分Tab页处于隐藏状态。

    根据业务需要进行调整。

    --min-ram-reserved 40 --sd-dynamic-cache

    缓存Stable Diffusion大模型到内存中。

    无。

  • 集群版参数

    说明

    ckpt的大模型和ControlNet的大模型会自动加载公共目录下的文件和您自定义的文件。

    集群版参数

    功能说明

    使用建议

    --lora-dir

    指定公共LoRA模型目录,例如:--lora-dir /code/stable-diffusion-webui/data-oss/models/Lora

    默认不配置,用户的所有LoRA目录将被隔离,并且只加载用户文件夹中的LoRA模型。当指定特定目录后,所有的用户将同时加载该公共目录中的LoRA模型和用户文件夹中的LoRA模型。

    --vae-dir

    指定公共VAE模型目录,例如:--vae-dir /code/stable-diffusion-webui/data-oss/models/VAE

    默认不配置,用户的所有VAE目录将被隔离,并且只加载用户文件夹中的VAE模型。当指定特定目录后,所有的用户只加载该公共目录下的VAE模型。

    --gfpgan-dir

    指定公共GFPGAN模型目录,例如:--gfpgan-dir /code/stable-diffusion-webui/data-oss/models/GFPGAN

    默认不配置,用户的所有GFPGAN目录将被隔离,并且只加载用户文件夹中的GFPGAN模型。当指定特定目录后,所有的用户只加载该公共目录下的GFPGAN模型。

    --embeddings-dir

    指定公共embeddings模型目录,例如:--embeddings-dir /code/stable-diffusion-webui/data-oss/embeddings

    默认不配置,用户的所有embeddings目录将被隔离,并且只加载用户文件夹中的embeddings模型。当指定特定目录后,所有的用户只加载该公共目录下的embeddings模型。

    --hypernetwork-dir

    指定公共hypernetwork模型目录,例如:--hypernetwork-dir /code/stable-diffusion-webui/data-oss/models/hypernetworks

    默认不配置,用户的所有hypernetwork目录将被隔离,并且只加载用户文件夹中的hypernetwork模型。当指定特定目录后,所有的用户只加载该公共目录下的hypernetwork模型。

    --root-extensions

    插件目录使用共享目录。使用该参数后,所有用户看到的插件完全相同。

    需要集中安装插件或集中管理插件时使用该参数。

API接口额外支持配置的参数有哪些?

EAS基于原生Stable Diffusion WebUI接口支持了一些新特性,在API接口中除了必填参数以外,还可以添加一些可选参数用于实现更加丰富的功能或定制化需求:

  • 可以指定Stable Diffusion模型、VAE模型以及保存目录。

  • 支持通过URL输入参数,并返回相应的状态码。

  • 生成的图片和ControlNet所对应的图片可以通过URL进行访问。

具体使用示例如下:

txt2img请求和返回示例

请求数据格式示例如下:

{
      "alwayson_scripts": {
          "sd_model_checkpoint": "deliberate_v2.safetensors",  
          "save_dir": "/code/stable-diffusion-webui/data-oss/outputs",
          "sd_vae": "Automatic"
      },
      "steps": 20,
      "prompt": "girls",          
      "batch_size": 1,                                            
      "n_iter": 2,                                                 
      "width": 576, 
      "height": 576,
      "negative_prompt": "ugly, out of frame"
  }

其中关键参数说明如下:

  • sd_model_checkpoint:指定Stable Diffusion模型参数,并且可以自动切换到大模型。

  • sd_vae:指定VAE模型。

  • save_dir:指定生成图片的保存路径。

发送同步接口请求示例如下:

# 调用同步接口验证模型效果。

curl --location --request POST '<service_url>/sdapi/v1/txt2img' \
--header 'Authorization: <token>' \
--header 'Content-Type: application/json' \
--data-raw '{
      "alwayson_scripts": {
          "sd_model_checkpoint": "deliberate_v2.safetensors",
          "save_dir": "/code/stable-diffusion-webui/data-oss/outputs",
          "sd_vae": "Automatic"
      },
      "prompt": "girls",          
      "batch_size": 1,                                            
      "n_iter": 2,                                                 
      "width": 576, 
      "height": 576,
      "negative_prompt": "ugly, out of frame"
  }'

返回数据格式示例如下:

{
  "images": [],
  "parameters": {
    "id_task": "14837",
    "status": 0,
    "image_url": "/code/stable-diffusion-webui/data-oss/outputs/txt2img-grids/2023-07-24/grid-29a67c1c-099a-4d00-8ff3-1ebe6e64931a.png,/code/stable-diffusion-webui/data-oss/outputs/txt2img-images/2023-07-24/74626268-6c81-45ff-90b7-faba579dc309-1146644551.png,/code/stable-diffusion-webui/data-oss/outputs/txt2img-images/2023-07-24/6a233060-e197-4169-86ab-1c18adf04e3f-1146644552.png",
    "seed": "1146644551,1146644552",
    "error_msg": "",
    "total_time": 32.22393465042114
  },
  "info": ""
}

发送异步接口请求示例如下:

# 将数据直接送入异步队列。
curl --location --request POST '<service_url>/sdapi/v1/txt2img' \
--header 'Authorization: <token>' \
--header 'Content-Type: application/json' \
--data-raw '{
    "alwayson_scripts": {
        "sd_model_checkpoint": "deliberate_v2.safetensors",
        "id_task": "14837",
        "uid": "123",
        "save_dir": "tmp/outputs"
    },
    "prompt": "girls",
    "batch_size": 1,
    "n_iter": 2,
    "width": 576,
    "height": 576,
    "negative_prompt": "ugly, out of frame"
}'

img2img请求数据格式示例

请求数据格式示例如下:

{
    "alwayson_scripts": {
        "image_link":"https://eas-cache-cn-hangzhou.oss-cn-hangzhou-internal.aliyuncs.com/stable-diffusion-cache/tests/boy.png",
        "sd_model_checkpoint": "deliberate_v2.safetensors",
        "sd_vae": "Automatic",
        "save_dir": "/code/stable-diffusion-webui/data-oss/outputs"
    },
    "prompt": "girl",
    "batch_size": 1,                                            
    "n_iter": 2,                                                 
    "width": 576, 
    "height": 576,
    "negative_prompt": "ugly, out of frame",
    "steps": 20, # Sampling steps
    "seed": 111,   
    "subseed": 111, # Variation seed
    "subseed_strength": 0, # Variation strength
    "seed_resize_from_h": 0, # Resize seed from height
    "seed_resize_from_w": 0, # Resize seed from width
    "seed_enable_extras": false, # Extra
    "sampler_name": "DDIM", # Sampling method
    "cfg_scale": 7.5, # CFG Scale
    "restore_faces": true, # Restore faces
    "tiling": false, # Tiling
    "init_images": [], # image base64 str, default None
    "mask_blur": 4, # Mask blur
    "resize_mode": 1, # 0 just resize, 1 crop and resize, 2 resize and fill, 3 just resize
    "denoising_strength": 0.75, # Denoising strength
    "inpainting_mask_invert": 0, #int, index of ['Inpaint masked', 'Inpaint not masked'], Mask mode
    "inpainting_fill": 0, #index of ['fill', 'original', 'latent noise', 'latent nothing'], Masked content
    "inpaint_full_res": 0, # index of ["Whole picture", "Only masked"], Inpaint area
    "inpaint_full_res_padding": 32, #minimum=0, maximum=256, step=4, value=32, Only masked padding, pixels
    #"image_cfg_scale": 1, # resized by scale
    #"script_name": "Outpainting mk2", # 使用的script名字,不使用的话不要加这个字段
    #"script_args": ["Outpainting", 128, 8, ["left", "right", "up", "down"], 1, 0.05]  # 对应script脚本的参数,此处依次对应: 固定字段, pixels, mask_blur, direction, noise_q, color_variation
}

返回数据格式示例如下:

{
    "images":[],
    "parameters":{
        "id_task":"14837",
        "status":0,
        "image_url":"/data/api_test/img2img-grids/2023-06-05/grid-0000.png,/data/api_test/img2img-images/2023-06-05/00000-1003.png,/data/api_test/img2img-images/2023-06-05/00001-1004.png",
        "seed":"1003,1004",
        "error_msg":""
    },
    "info":""
}

txt2img使用controlnet的数据格式

请求数据格式如下:

{
    "alwayson_scripts": {
        "sd_model_checkpoint": "deliberate_v2.safetensors", #模型名称,需要带着 
        "save_dir": "/code/stable-diffusion-webui/data-oss/outputs",
        "controlnet":{
            "args":[
                {
                    "image_link": "https://pai-aigc-dataset.oss-cn-hangzhou.aliyuncs.com/pixabay_images/00008b87bf3ff6742b8cf81c358b9dbc.jpg",
                    "enabled": true, 
                    "module": "canny", 
                    "model": "control_v11p_sd15_canny", 
                    "weight": 1, 
                    "resize_mode": "Crop and Resize", 
                    "low_vram": false, 
                    "processor_res": 512, 
                    "threshold_a": 100, 
                    "threshold_b": 200, 
                    "guidance_start": 0, 
                    "guidance_end": 1, 
                    "pixel_perfect": true, 
                    "control_mode": "Balanced", 
                    "input_mode": "simple", 
                    "batch_images": "", 
                    "output_dir": "", 
                    "loopback": false
                }
            ]
        }
    },
    # 主要参数
    "prompt": "girls",          
    "batch_size": 1,                                            
    "n_iter": 2,                                                 
    "width": 576, 
    "height": 576,
    "negative_prompt": "ugly, out of frame"
}

返回数据格式示例如下:

{
    "images":[],
    "parameters":{
        "id_task":"14837",
        "status":0,
        "image_url":"/data/api_test/txt2img-grids/2023-06-05/grid-0007.png,/data/api_test/txt2img-images/2023-06-05/00014-1003.png,/data/api_test/txt2img-images/2023-06-05/00015-1004.png",
        "seed":"1003,1004",
        "error_msg":"",
        "image_mask_url":"/data/api_test/controlnet_mask/2023-06-05/00000.png,/data/api_test/controlnet_mask/2023-06-05/00001.png"
    },
    "info":""
}

相关文档

通过EAS,您还可以完成以下场景化部署:

  • 部署支持WebUIAPI调用的LLM大语言模型,并在部署LLM应用后,利用LangChain框架集成企业知识库,实现智能问答和自动化功能。详情请参见5分钟使用EAS一键部署LLM大语言模型应用

  • 部署基于ComfyUIStable Video Diffusion模型的AI视频生成服务,帮助您完成社交平台短视频内容生成、动画制作等任务。详情请参见AI视频生成-ComfyUI部署

  • 部署集成了大语言模型(LLM)和检索增强生成(RAG)技术的对话系统服务,适用于问答、摘要生成和依赖外部知识的自然语言处理任务。详情请参见大模型RAG对话系统

  • AI绘画场景中,您可以将经过训练的LoRa模型应用于StableDiffusion(SD)服务,作为辅助模型,以提升SD绘画的效果,详情请参见5分钟使用EAS一键部署Kohya SD模型微调应用

  • 更多关于服务调用时支持使用的接口列表和使用示例,请参见服务调用SDK

  • 更多关于EAS产品的计费详情,请参见模型在线服务(EAS)计费说明