Stable-diffusion WebUI API呼叫方法

2023-10-16 21:00:25
寫這篇文章的主要原因是工作中需要寫一個用訓練好的模型批次生圖的指令碼,開始是想用python直接載入模型,但後來發現webui的介面中有不少好用的外掛和引數,所以最終改成呼叫WebUI介面的方式來批次生圖。

Stable-diffusion的webui介面使用比較方便,但是它的api檔案比較簡陋,很多功能需要去看原始碼,所以在這裡記錄下主要的呼叫方法

相關檔案

官方檔案:https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/API

執行方式

# 1. 首先需要在webui-user.bat中給COMMANDLINE_ARGS新增--api引數
# 2. 啟動命令中需要新增nowebui
python launch.py --nowebui

然後使用http://10.45.128.130:8085/docs即可檢視官方檔案,需要替換ip:port為自己的地址才能看到,官方檔案中有執行按鈕可以執行example,能簡單的看下返回效果

## -- api呼叫範例程式碼 -- ##
import json
import base64
import requests

# 傳送請求
def submit_post(url: str, data: dict):
    return requests.post(url, data=json.dumps(data))

# 解碼並儲存圖片
def save_encoded_image(b64_image: str, output_path: str):
    with open(output_path, 'wb') as image_file:
        image_file.write(base64.b64decode(b64_image))


if __name__ == '__main__':
    txt2img_url = r'http://127.0.0.1:8085/sdapi/v1/txt2img'

    data = {'prompt': 'a dog wearing a hat',
    'negative_prompt': '',
    'sampler_index': 'DPM++ SDE',
    'seed': 1234,
    'steps': 20,
    'width': 512,
    'height': 512,
    'cfg_scale': 8}

    response = submit_post(txt2img_url, data)
    save_image_path = r'./result/tmp.png'
    save_encoded_image(response.json()['images'][0], save_image_path)

/sdapi/v1/txt2img介面scripts參數列,以xyz plot為例

{
  "enable_hr": false,
  "denoising_strength": 0,
  "firstphase_width": 0,
  "firstphase_height": 0,
  "hr_scale": 2,
  "hr_upscaler": "",
  "hr_second_pass_steps": 0,
  "hr_resize_x": 0,
  "hr_resize_y": 0,
  "hr_sampler_name": "",
  "hr_prompt": "",
  "hr_negative_prompt": "",
  "prompt": "cute girl with short brown hair in black t-shirt in animation style",
  "styles": [
    ""
  ],
  "seed": -1,
  "subseed": -1,
  "subseed_strength": 0,
  "seed_resize_from_h": -1,
  "seed_resize_from_w": -1,
  "sampler_name": "Euler a",
  "batch_size": 1,
  "n_iter": 1,
  "steps": 50,
  "cfg_scale": 7,
  "width": 512,
  "height": 512,
  "restore_faces": false,
  "tiling": false,
  "do_not_save_samples": false,
  "do_not_save_grid": false,
  "negative_prompt": "",
  "eta": 0,
  "s_min_uncond": 0,
  "s_churn": 0,
  "s_tmax": 0,
  "s_tmin": 0,
  "s_noise": 1,
  "override_settings": {},
  "override_settings_restore_afterwards": true,
  "script_args": [4,"20,30",[],9,"Euler a, LMS",[],0,"",[],"True","False","False","False",0], # xyz plot引數
  "sampler_index": "Euler",
  "script_name": "X/Y/Z Plot",
  "send_images": true,
  "save_images": false,
  "alwayson_scripts": {}
}

第三方開源庫(推薦)

https://github.com/mix1009/sdwebuiapi

這個開源庫是webui官方推薦的,將大多數api的使用方法都整合到一起了,而且還提供了scripts引數的使用方式。雖然這個庫已經很久沒有更新了,很多issue也沒有解決,但不妨礙我們參考它的函數使用方式。我們在使用的使用可以直接import webuiapi,也可以參照他們的實現方式來直接呼叫官方介面。

import webuiapi
from PIL import Image

# create API client with custom host, port
api = webuiapi.WebUIApi(host='127.0.0.1', port=8085)

XYZPlotAvailableTxt2ImgScripts = [...] # 根據指令碼引數自行增加調整xyz軸可選擇的引數內容

# 省略部分引數定義
... 

# 引數與官方檔案的txt2img完全一致,參照上文引數檔案
result = api.txt2img(
    prompt="cute girl with short brown hair in black t-shirt in animation style",
    seed=1003,
    script_name="X/Y/Z Plot",
    script_args=[
        XYZPlotAvailableTxt2ImgScripts.index(XAxisType), # index,對應xyz軸每個變數在卷軸中的索引數
        XAxisValues,																		 # 選擇的對應座標軸的變數值
        [], 																						 # 變數值下拉選單,webui庫更新的1.16之後,新增的引數,必填,不然無法執行生圖操作
        XYZPlotAvailableTxt2ImgScripts.index(YAxisType),
        YAxisValues,
        ["manikin_model_album6_576_768_20.safetensors","manikin_model_album6_576_768_20-000016.safetensors"],
        XYZPlotAvailableTxt2ImgScripts.index(ZAxisType),
        ZAxisValues,
        [],
        drawLegend,
        includeLoneImages,
        includeSubGrids,
        noFixedSeeds,
        marginSize,
        ]
)


# save image with jpg format
img = result.image
img.save("./result/output2.jpg", quality=90)