AdvancedParams
用 adp
代替,名称变动的原则是和 Fooocus 进行统一:
Fooocus-API | FooocusAPI | 备注 |
---|---|---|
prompt | prompt | |
negative_prompt | negative_prompt | |
style_selections | style_selections | |
performance_selection | performance_selection | |
aspect_ratios_selection | aspect_ratios_selection | |
image_number | image_number | |
image_seed | image_seed | |
sharpness | sharpness | |
guidance_scale | guidance_scale | |
base_model_name | base_model_name | |
refiner_model_name | refiner_model_name | |
refiner_switch | refiner_switch | |
loras | loras | 传入格式相同,都是 Lora 对象列表 |
input_image_checkbox | 可以忽略,它总是为 True | |
current_tab | 可以忽略,根据参数会自动判断 | |
uov_method | uov_method | |
input_image | uov_input_image | 使用 Fooocus 的变量名称 |
outpaint_selections | outpaint_selections | |
input_image | inpaint_input_image | 使用 Fooocus 的变量名称 |
inpaint_additional_prompt | inpaint_additional_prompt | |
input_mask | inpaint_mask_image_upload | 使用 Fooocus 的变量名称 |
adp.disable_preview | disable_preview | |
adp.disable_intermediate_results | disable_intermediate_results | |
adp.disable_seed_increment | disable_seed_increment | |
adp.black_out_nsfw | black_out_nsfw | |
adp.adm_scaler_positive | adm_scaler_positive | |
adp.adm_scaler_negative | adm_scaler_negative | |
adp.adm_scaler_end | adm_scaler_end | |
adp.adaptive_cfg | adaptive_cfg | |
adp.clip_skip | clip_skip | |
adp.sampler_name | sampler_name | |
adp.scheduler_name | scheduler_name | |
adp.vae_name | vae_name | |
adp.overwrite_step | overwrite_step | |
adp.overwrite_switch | overwrite_switch | |
adp.overwrite_width | overwrite_width | |
adp.overwrite_height | overwrite_height | |
adp.overwrite_vary_strength | overwrite_vary_strength | |
adp.overwrite_upscale_strength | overwrite_upscale_strength | |
adp.mixing_image_prompt_and_vary_upscale | mixing_image_prompt_and_vary_upscale | |
adp.mixing_image_prompt_and_inpaint | mixing_image_prompt_and_inpaint | |
adp.debugging_cn_preprocessor | debugging_cn_preprocessor | |
adp.skipping_cn_preprocessor | skipping_cn_preprocessor | |
adp.canny_low_threshold | canny_low_threshold | |
adp.canny_high_threshold | canny_high_threshold | |
adp.refiner_swap_method | refiner_swap_method | |
adp.controlnet_softness | controlnet_softness | |
adp.freeu_enabled | freeu_enabled | |
adp.freeu_b1 | freeu_b1 | |
adp.freeu_b2 | freeu_b2 | |
adp.freeu_s1 | freeu_s1 | |
adp.freeu_s2 | freeu_s2 | |
adp.debugging_inpaint_preprocessor | debugging_inpaint_preprocessor | |
adp.inpaint_disable_initial_latent | inpaint_disable_initial_latent | |
adp.inpaint_engine | inpaint_engine | |
adp.inpaint_strength | inpaint_strength | |
adp.inpaint_respective_field | inpaint_respective_field | |
adp.inpaint_mask_upload_checkbox | inpaint_mask_upload_checkbox | |
adp.invert_mask_checkbox | invert_mask_checkbox | |
adp.inpaint_erode_or_dilate | inpaint_erode_or_dilate | |
image_prompts | controlnet_image | 只是属性名称变更 |
generate_image_grid | 新增,这是个测试选项,建议默认 | |
outpaint_distance_left | outpaint_distance | 这四个属性合并为了一个属性 |
outpaint_distance_right | 可以通过一个列表传递这四个值 | |
outpaint_distance_top | 例如:[100, 50, 0, 0] | |
outpaint_distance_bottom | 方向是:左, 上, 右, 下 | |
upscale_value | upscale_multiple | 属性名变更 |
preset | 新增,可以通过该属性指定使用的预设 | |
stream_output | 新增流式输出,类似 LLM 的流式输出 | |
save_meta | save_metadata_to_images | |
meta_scheme | metadata_scheme | |
save_extension | output_format | |
save_name | 移除,不支持自定义文件名 | |
read_wildcards_in_order | read_wildcards_in_order | |
require_base64 | require_base64 | 该参数后续可能会被移除 |
async_process | async_process | |
webhook_url | webhook_url |
简单说来就是
- 将所有
AdvancedParams
平移到上一级 - 修改部分参数名
input_image
->inpaint_input_image
inpaint_mask
->inpaint_mask_image_upload
input_image
->uov_input_image
image_prompts
->controlnet_image
upscale_value
->upscale_value
save_meta
->upscale_multiple
meta_scheme
->save_metadata_to_images
save_extension
->output_format
- 移除部分参数名
save_name
- 增加部分参数
input_image_checkbox
current_tab
generate_image_grid
preset
stream_output
- 合并部分参数
outpaint_distance_left,right,top,bottom
四个参数合并为outpaint_distance
在参数中指定 async_process
为 True
import requests
import json
endpoint = "http://127.0.0.1:7866/v1/engine/generate/"
params = {
"prompt": "",
"negative_prompt": "",
"performance_selection": "Lightning",
"async_process": True,
"webhook_url": ""
}
res = requests.post(
url=endpoint,
data=json.dumps(params),
timeout=60
)
print(res.json())
输出如下:
{'id': -1, 'task_id': '85c10c81e9e2482d90a64c3704137d3a', 'req_params': {}, 'in_queue_mills': -1, 'start_mills': -1, 'finish_mills': -1, 'task_status': 'pending', 'progress': -1, 'preview': '', 'webhook_url': '', 'result': []}
你可以通过 task_id
访问 http://127.0.0.1:7866/tasks/{task_id}
获取任务信息,如果该任务正在执行,返回信息中会包含 preview
返回数据示例:
# 未开始
{
"id": -1,
"in_queue_mills": 1720085748199,
"finish_mills": null,
"progress": null,
"result": null,
"req_params": {
# 完整的请求参数
...
},
"task_id": "85c10c81e9e2482d90a64c3704137d3a",
"start_mills": null,
"task_status": null,
"webhook_url": ""
}
# 执行中
{
"id": -1,
"task_id": "85c10c81e9e2482d90a64c3704137d3a",
"req_params": {
...
},
"in_queue_mills": 1720086131653,
"start_mills": 1720086131865,
"finish_mills": -1,
"task_status": "running",
"progress": 18,
"preview": "a long text",
"webhook_url": "",
"result": []
}
# 已完成
{
"id": 71,
"in_queue_mills": 1720085748199,
"finish_mills": 1720085770046,
"progress": 100,
"result": [
"http://127.0.0.1:7866/outputs/2024-07-04/2024-07-04_17-36-09_5201.png"
],
"req_params": {
...
},
"task_id": "85c10c81e9e2482d90a64c3704137d3a",
"start_mills": 1720085748425,
"task_status": "finished",
"webhook_url": ""
}
这是一个类似 LLM 流式输出的方式,你会持续收到来自服务器的信息,直到结束,参照上面的示例:
import requests
import json
endpoint = "http://127.0.0.1:7866/v1/engine/generate/"
params = {
"prompt": "",
"negative_prompt": "",
"performance_selection": "Lightning",
"stream_output": True,
"webhook_url": ""
}
res = requests.post(
url=endpoint,
data=json.dumps(params),
stream=True,
timeout=60
)
for line in res.iter_lines():
if line:
print(line.decode('utf-8'))
你会获得类似下面的输出:
data: {"progress": 2, "preview": null, "message": "Loading models ...", "images": []}
data:
data: {"progress": 13, "preview": null, "message": "Preparing task 1/1 ...", "images": []}
data:
data: {"progress": 13, "preview": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASAAAA...", 'message': 'Sampling step 1/4, image 1/1 ...', 'images': []}
data:
data: {"progress": 34, "preview": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASAAAA...", 'message': 'Sampling step 2/4, image 1/1 ...', 'images': []}
data:
data: {"progress": 56, "preview": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASAAAA...", 'message': 'Sampling step 3/4, image 1/1 ...', 'images': []}
data:
data: {"progress": 78, "preview": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASAAAA...", 'message': 'Sampling step 4/4, image 1/1 ...', 'images': []}
data:
data: {"progress": 100, "preview": null, "message": "Saving image 1/1 to system ...", "images": []}
data:
data: {"progress": 100, "preview": null, "message": "Finished", "images": ["http://10.0.0.245:7866/outputs/2024-07-05/2024-07-05_09-31-10_1752.png"]}
data:
我们在稍微修改下:
import requests
import json
endpoint = "http://127.0.0.1:7866/v1/engine/generate/"
params = {
"prompt": "",
"negative_prompt": "",
"performance_selection": "Lightning",
"stream_output": True,
"webhook_url": ""
}
res = requests.post(
url=endpoint,
data=json.dumps(params),
stream=True,
timeout=60
)
for line in res.iter_lines(chunk_size=8192):
line = line.decode('utf-8').split('\n')[0]
try:
json_data = json.loads(line[6:])
if json_data["preview"] is not None:
json_data["preview"] = "data:image/png;base64,iVBORw0KGgoAAAANSU..."
except json.decoder.JSONDecodeError:
continue
print(json_data)
然后你就得到了一系列类似这样的输出:
{'progress': 13, 'preview': None, 'message': 'Preparing task 1/1 ...', 'images': []}
{'progress': 13, 'preview': 'data:image/png;base64,iVBORw0KGgoAAAANSU...', 'message': 'Sampling step 1/4, image 1/1 ...', 'images': []}
{'progress': 34, 'preview': 'data:image/png;base64,iVBORw0KGgoAAAANSU...', 'message': 'Sampling step 2/4, image 1/1 ...', 'images': []}
{'progress': 56, 'preview': 'data:image/png;base64,iVBORw0KGgoAAAANSU...', 'message': 'Sampling step 3/4, image 1/1 ...', 'images': []}
{'progress': 78, 'preview': 'data:image/png;base64,iVBORw0KGgoAAAANSU...', 'message': 'Sampling step 4/4, image 1/1 ...', 'images': []}
{'progress': 100, 'preview': None, 'message': 'Saving image 1/1 to system ...', 'images': []}
{'progress': 100, 'preview': None, 'message': 'Finished', 'images': ['http://10.0.0.245:7866/outputs/2024-07-05/2024-07-05_10-02-22_2536.png']}
这还挺适合前端套壳用的(可惜我完全搞不懂前端,要不高低套一个),比如我用 AI 生成了一个 example.html ,服务启动后点击 Generate
按钮,你就会得到一个有预览、有进度的生成过程。
这个就简单了,它就是返回一张图片,不过需要在请求时将 async_process
和 stream_output
同时指定为 false
,此时 image_number
强制为 1
import requests
import json
from PIL import Image
from io import BytesIO
import matplotlib.pyplot as plt
endpoint = "http://127.0.0.1:7866/v1/engine/generate/"
params = {
"prompt": "",
"negative_prompt": "",
"performance_selection": "Lightning",
"async_process": False,
"stream_output": False,
"webhook_url": ""
}
res = requests.post(
url=endpoint,
data=json.dumps(params),
timeout=60
)
image_stream = BytesIO(res.content)
image = Image.open(image_stream)
plt.imshow(image)
plt.show()
和 Fooocus-API 不同的是历史记录的保存将是自动进行的,没有保留开关。数据库使用 SQLite3
并存放在 outputs/db.sqlite3
中。同时吸取了上次的教训,极大简化了表结构,将请求参数作为 JSON 存放在 req_params
字段。为了降低读写,仅在任务进入队列时和完成后进行数据库操作。其仅作为生成记录使用,任务状态的追踪会在内存中完成。
此外,该版本会保留输入图像,上传的图像会计算哈希值并保存在 inputs
目录,数据库中的 req_params
会将图片参数替换为 url
信息进行保存,这意味着更完整的历史记录保存,无论是文生图还是图生图又或者是其他
这是个复合接口,但其返回格式是固定的,该接口总是会返回下面格式的 JSON 数据,无论参数如何指定
{
"history": [],
"current": [], # 尽管是个列表,但其中不会超过一个元素。
"pending": []
}
所有的元素其格式都是和数据库中的 scheme 匹配的,除了 current
会多一个 preview
,比如下图:
该接口还支持更加精细的用法,参考下面的示例:
该接口返回格式总是固定的,不管参数如何调整
curl http://localhost:7866/tasks?query=current
# 仅返回当前任务,query 参数还可以指定的值为 'all', 'pending', 'history'
curl http://localhost:7866/tasks?query=history&page=3&page_size=5
# history 和 pending 支持分页和页面大小
curl http://localhost:7866/tasks?query=history&start_at=2024-07-03T12:22:30
# 你可以指定一个时间范围进行查询,这会返回该时间段的所有记录。时间格式是 ISO8601,如果你不指定 end_at 则截止当前时间
curl http://localhost:7866/tasks?query=history&start_at=2024-07-03T12:22:30&action=delete
# 删除指定时间范围的任务,数据库记录和生成文件。目前仅支持这一种删除方法(不会删除 input 文件)。
curl http://localhost:7866/tasks/38ba92b188a64233a7336218cd902865
# 这会返回该任务的信息,但它只是一个字典。相当于从上面列表中取出指定 task_id 的任务,如果它刚好是当前任务,那它也会包含 preview