kiapi 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- kiapi/__init__.py +3 -0
- kiapi/__main__.py +4 -0
- kiapi/api/__init__.py +26 -0
- kiapi/api/_constants/require_auth.py +14 -0
- kiapi/api/_helpers/build_job_responses.py +73 -0
- kiapi/api/_helpers/build_openapi.py +55 -0
- kiapi/api/_helpers/build_train_responses.py +21 -0
- kiapi/api/_helpers/get_accept.py +20 -0
- kiapi/api/_helpers/get_ctx.py +7 -0
- kiapi/api/_helpers/get_worker.py +7 -0
- kiapi/api/_helpers/register_capability_endpoints.py +70 -0
- kiapi/api/_helpers/submit_and_maybe_wait.py +113 -0
- kiapi/api/_settings.py +50 -0
- kiapi/api/_views/async_job_response.py +21 -0
- kiapi/api/_views/capability_model_spec.py +49 -0
- kiapi/api/app.py +150 -0
- kiapi/api/audio/acestep/_views/extract_response.py +57 -0
- kiapi/api/audio/acestep/_views/track_response.py +57 -0
- kiapi/api/audio/acestep/router.py +190 -0
- kiapi/api/audio/audiogen/_views/audio_response.py +46 -0
- kiapi/api/audio/audiogen/router.py +77 -0
- kiapi/api/chat/_views/chat_completion_response.py +71 -0
- kiapi/api/chat/router.py +253 -0
- kiapi/api/embedding/_views/embedding_response.py +35 -0
- kiapi/api/embedding/router.py +82 -0
- kiapi/api/files/_operations/get_file.py +14 -0
- kiapi/api/files/_operations/get_file_id.py +18 -0
- kiapi/api/files/_views/file_delete_response.py +14 -0
- kiapi/api/files/_views/file_list_response.py +15 -0
- kiapi/api/files/router.py +105 -0
- kiapi/api/health/_views/health_response.py +26 -0
- kiapi/api/health/router.py +28 -0
- kiapi/api/image/depthpro/_views/estimate_response.py +70 -0
- kiapi/api/image/depthpro/router.py +81 -0
- kiapi/api/image/ernie/_views/image_response.py +50 -0
- kiapi/api/image/ernie/router.py +181 -0
- kiapi/api/image/flux2/_views/image_response.py +53 -0
- kiapi/api/image/flux2/router.py +197 -0
- kiapi/api/image/ideogram4/_views/image_response.py +55 -0
- kiapi/api/image/ideogram4/router.py +87 -0
- kiapi/api/image/qwen/_views/image_response.py +47 -0
- kiapi/api/image/qwen/router.py +141 -0
- kiapi/api/image/seedvr2/_views/image_response.py +50 -0
- kiapi/api/image/seedvr2/router.py +83 -0
- kiapi/api/image/zimage/_views/image_response.py +49 -0
- kiapi/api/image/zimage/router.py +131 -0
- kiapi/api/jobs/_operations/get_job_id.py +18 -0
- kiapi/api/jobs/_views/job_delete_response.py +19 -0
- kiapi/api/jobs/_views/job_list_response.py +15 -0
- kiapi/api/jobs/router.py +62 -0
- kiapi/api/models/_schemas/openai_model_spec.py +26 -0
- kiapi/api/models/_views/model_list_response.py +15 -0
- kiapi/api/models/router.py +29 -0
- kiapi/api/video/ltx2/_views/__init__.py +1 -0
- kiapi/api/video/ltx2/_views/video_response.py +59 -0
- kiapi/api/video/ltx2/router.py +89 -0
- kiapi/api/web/_views/__init__.py +7 -0
- kiapi/api/web/_views/fetch_api_request.py +26 -0
- kiapi/api/web/_views/fetch_error_response.py +25 -0
- kiapi/api/web/router.py +302 -0
- kiapi/capabilities/__init__.py +24 -0
- kiapi/capabilities/_exceptions/CapabilityError.py +2 -0
- kiapi/capabilities/_exceptions/ValidationError.py +2 -0
- kiapi/capabilities/_helpers/attach_mflux_progress.py +50 -0
- kiapi/capabilities/_helpers/get_file_path.py +20 -0
- kiapi/capabilities/_helpers/resolve_file_ref.py +16 -0
- kiapi/capabilities/acestep/README.ja.md +174 -0
- kiapi/capabilities/acestep/README.md +167 -0
- kiapi/capabilities/acestep/__init__.py +37 -0
- kiapi/capabilities/acestep/_constants/description.py +122 -0
- kiapi/capabilities/acestep/_exceptions/ace_step_engine_error.py +2 -0
- kiapi/capabilities/acestep/_helpers/register.py +96 -0
- kiapi/capabilities/acestep/_models/acestep.py +105 -0
- kiapi/capabilities/acestep/_operations/handle_cover.py +23 -0
- kiapi/capabilities/acestep/_operations/handle_extract.py +38 -0
- kiapi/capabilities/acestep/_operations/handle_generate.py +18 -0
- kiapi/capabilities/acestep/_operations/handle_repaint.py +25 -0
- kiapi/capabilities/acestep/_operations/resolve_ace_step_paths.py +30 -0
- kiapi/capabilities/acestep/_operations/resolve_cover_params.py +21 -0
- kiapi/capabilities/acestep/_operations/resolve_engine.py +10 -0
- kiapi/capabilities/acestep/_operations/resolve_extract_params.py +24 -0
- kiapi/capabilities/acestep/_operations/resolve_generate_params.py +18 -0
- kiapi/capabilities/acestep/_operations/resolve_repaint_params.py +22 -0
- kiapi/capabilities/acestep/_schemas/ace_step_paths.py +29 -0
- kiapi/capabilities/acestep/_services/ace_step_engine.py +143 -0
- kiapi/capabilities/acestep/_settings.py +82 -0
- kiapi/capabilities/acestep/_views/ace_step_base.py +61 -0
- kiapi/capabilities/acestep/_views/cover_params.py +26 -0
- kiapi/capabilities/acestep/_views/cover_request.py +49 -0
- kiapi/capabilities/acestep/_views/extract_params.py +24 -0
- kiapi/capabilities/acestep/_views/extract_request.py +33 -0
- kiapi/capabilities/acestep/_views/generate_params.py +25 -0
- kiapi/capabilities/acestep/_views/generate_request.py +54 -0
- kiapi/capabilities/acestep/_views/repaint_params.py +27 -0
- kiapi/capabilities/acestep/_views/repaint_request.py +51 -0
- kiapi/capabilities/acestep/_views/track_params.py +7 -0
- kiapi/capabilities/acestep/worker_subprocess.py +247 -0
- kiapi/capabilities/audiogen/README.ja.md +49 -0
- kiapi/capabilities/audiogen/README.md +48 -0
- kiapi/capabilities/audiogen/__init__.py +25 -0
- kiapi/capabilities/audiogen/_constants/description.py +60 -0
- kiapi/capabilities/audiogen/_helpers/attach_audiogen_progress.py +27 -0
- kiapi/capabilities/audiogen/_helpers/register.py +42 -0
- kiapi/capabilities/audiogen/_helpers/validate_generate.py +14 -0
- kiapi/capabilities/audiogen/_models/audiogen.py +98 -0
- kiapi/capabilities/audiogen/_operations/handle_generate.py +27 -0
- kiapi/capabilities/audiogen/_operations/resolve_generate_params.py +25 -0
- kiapi/capabilities/audiogen/_settings.py +34 -0
- kiapi/capabilities/audiogen/_views/generate_params.py +14 -0
- kiapi/capabilities/audiogen/_views/generate_request.py +96 -0
- kiapi/capabilities/chat/README.ja.md +822 -0
- kiapi/capabilities/chat/README.md +806 -0
- kiapi/capabilities/chat/__init__.py +25 -0
- kiapi/capabilities/chat/_constants/description.py +163 -0
- kiapi/capabilities/chat/_helpers/register.py +67 -0
- kiapi/capabilities/chat/_models/qwen3_5.py +183 -0
- kiapi/capabilities/chat/_models/qwen3_omni.py +242 -0
- kiapi/capabilities/chat/_operations/apply_template.py +74 -0
- kiapi/capabilities/chat/_operations/completed_hermes_tool_call_text.py +9 -0
- kiapi/capabilities/chat/_operations/emit_streaming_response.py +297 -0
- kiapi/capabilities/chat/_operations/ensure_streaming_detokenizer_compat.py +49 -0
- kiapi/capabilities/chat/_operations/format_response.py +72 -0
- kiapi/capabilities/chat/_operations/handle_chat.py +25 -0
- kiapi/capabilities/chat/_operations/parse_hermes_tool_calls.py +63 -0
- kiapi/capabilities/chat/_operations/parse_json_tool_calls.py +66 -0
- kiapi/capabilities/chat/_operations/parse_messages.py +326 -0
- kiapi/capabilities/chat/_operations/resolve_chat_params.py +50 -0
- kiapi/capabilities/chat/_operations/stream_text_from_tokens.py +32 -0
- kiapi/capabilities/chat/_operations/strip_tool_calls.py +15 -0
- kiapi/capabilities/chat/_settings.py +74 -0
- kiapi/capabilities/chat/_utils/apply_parallel_tool_call_policy.py +17 -0
- kiapi/capabilities/chat/_utils/apply_seed.py +8 -0
- kiapi/capabilities/chat/_utils/load_audio_mono.py +31 -0
- kiapi/capabilities/chat/_utils/load_mlx_vlm.py +12 -0
- kiapi/capabilities/chat/_utils/warmup_params.py +26 -0
- kiapi/capabilities/chat/_views/chat_params.py +34 -0
- kiapi/capabilities/chat/_views/chat_request.py +153 -0
- kiapi/capabilities/depthpro/README.ja.md +131 -0
- kiapi/capabilities/depthpro/README.md +124 -0
- kiapi/capabilities/depthpro/__init__.py +23 -0
- kiapi/capabilities/depthpro/_constants/description.py +39 -0
- kiapi/capabilities/depthpro/_helpers/register.py +46 -0
- kiapi/capabilities/depthpro/_helpers/validate_estimate.py +32 -0
- kiapi/capabilities/depthpro/_models/depthpro.py +144 -0
- kiapi/capabilities/depthpro/_operations/handle_estimate.py +50 -0
- kiapi/capabilities/depthpro/_operations/is_quantize_override.py +12 -0
- kiapi/capabilities/depthpro/_operations/resolve_estimate_params.py +24 -0
- kiapi/capabilities/depthpro/_settings.py +46 -0
- kiapi/capabilities/depthpro/_views/estimate_params.py +21 -0
- kiapi/capabilities/depthpro/_views/estimate_request.py +63 -0
- kiapi/capabilities/embedding/README.ja.md +137 -0
- kiapi/capabilities/embedding/README.md +128 -0
- kiapi/capabilities/embedding/__init__.py +24 -0
- kiapi/capabilities/embedding/_constants/description.py +47 -0
- kiapi/capabilities/embedding/_helpers/register.py +66 -0
- kiapi/capabilities/embedding/_models/qwen3_text.py +53 -0
- kiapi/capabilities/embedding/_models/qwen3_vl.py +97 -0
- kiapi/capabilities/embedding/_operations/format_response.py +24 -0
- kiapi/capabilities/embedding/_operations/handle_embed.py +24 -0
- kiapi/capabilities/embedding/_operations/parse_inputs.py +108 -0
- kiapi/capabilities/embedding/_operations/resolve_embed_params.py +18 -0
- kiapi/capabilities/embedding/_settings.py +27 -0
- kiapi/capabilities/embedding/_utils/to_vector.py +20 -0
- kiapi/capabilities/embedding/_views/embed_params.py +17 -0
- kiapi/capabilities/embedding/_views/embed_request.py +39 -0
- kiapi/capabilities/ernie/README.ja.md +242 -0
- kiapi/capabilities/ernie/README.md +223 -0
- kiapi/capabilities/ernie/__init__.py +34 -0
- kiapi/capabilities/ernie/_constants/description.py +71 -0
- kiapi/capabilities/ernie/_helpers/register.py +60 -0
- kiapi/capabilities/ernie/_helpers/validate_edit.py +19 -0
- kiapi/capabilities/ernie/_helpers/validate_generate.py +8 -0
- kiapi/capabilities/ernie/_models/ernie.py +356 -0
- kiapi/capabilities/ernie/_operations/handle_edit.py +39 -0
- kiapi/capabilities/ernie/_operations/handle_generate.py +38 -0
- kiapi/capabilities/ernie/_operations/handle_train.py +77 -0
- kiapi/capabilities/ernie/_operations/is_quantize_override.py +16 -0
- kiapi/capabilities/ernie/_operations/resolve_edit_params.py +44 -0
- kiapi/capabilities/ernie/_operations/resolve_generate_params.py +40 -0
- kiapi/capabilities/ernie/_operations/resolve_lora_params.py +23 -0
- kiapi/capabilities/ernie/_operations/resolve_train_params.py +43 -0
- kiapi/capabilities/ernie/_operations/validate_common.py +33 -0
- kiapi/capabilities/ernie/_schemas/lora_ref.py +27 -0
- kiapi/capabilities/ernie/_settings.py +151 -0
- kiapi/capabilities/ernie/_views/edit_params.py +36 -0
- kiapi/capabilities/ernie/_views/edit_request.py +142 -0
- kiapi/capabilities/ernie/_views/generate_params.py +32 -0
- kiapi/capabilities/ernie/_views/generate_request.py +127 -0
- kiapi/capabilities/ernie/_views/train_params.py +28 -0
- kiapi/capabilities/ernie/_views/train_request.py +96 -0
- kiapi/capabilities/flux2/README.ja.md +260 -0
- kiapi/capabilities/flux2/README.md +241 -0
- kiapi/capabilities/flux2/__init__.py +36 -0
- kiapi/capabilities/flux2/_constants/description.py +81 -0
- kiapi/capabilities/flux2/_helpers/register.py +98 -0
- kiapi/capabilities/flux2/_helpers/validate_edit.py +12 -0
- kiapi/capabilities/flux2/_helpers/validate_generate.py +8 -0
- kiapi/capabilities/flux2/_models/flux2.py +396 -0
- kiapi/capabilities/flux2/_operations/handle_edit.py +44 -0
- kiapi/capabilities/flux2/_operations/handle_generate.py +46 -0
- kiapi/capabilities/flux2/_operations/handle_train.py +105 -0
- kiapi/capabilities/flux2/_operations/is_quantize_override.py +16 -0
- kiapi/capabilities/flux2/_operations/resolve_edit_params.py +43 -0
- kiapi/capabilities/flux2/_operations/resolve_generate_params.py +44 -0
- kiapi/capabilities/flux2/_operations/resolve_lora_params.py +23 -0
- kiapi/capabilities/flux2/_operations/resolve_train_params.py +42 -0
- kiapi/capabilities/flux2/_operations/role_spec.py +13 -0
- kiapi/capabilities/flux2/_operations/split_repo.py +11 -0
- kiapi/capabilities/flux2/_operations/validate_common.py +35 -0
- kiapi/capabilities/flux2/_schemas/lora_ref.py +27 -0
- kiapi/capabilities/flux2/_settings.py +181 -0
- kiapi/capabilities/flux2/_views/edit_params.py +36 -0
- kiapi/capabilities/flux2/_views/edit_request.py +145 -0
- kiapi/capabilities/flux2/_views/generate_params.py +36 -0
- kiapi/capabilities/flux2/_views/generate_request.py +150 -0
- kiapi/capabilities/flux2/_views/train_params.py +32 -0
- kiapi/capabilities/flux2/_views/train_request.py +102 -0
- kiapi/capabilities/ideogram4/README.ja.md +230 -0
- kiapi/capabilities/ideogram4/README.md +219 -0
- kiapi/capabilities/ideogram4/__init__.py +24 -0
- kiapi/capabilities/ideogram4/_constants/description.py +65 -0
- kiapi/capabilities/ideogram4/_helpers/register.py +44 -0
- kiapi/capabilities/ideogram4/_helpers/validate_generate.py +31 -0
- kiapi/capabilities/ideogram4/_models/ideogram4.py +120 -0
- kiapi/capabilities/ideogram4/_operations/handle_generate.py +30 -0
- kiapi/capabilities/ideogram4/_operations/is_quantize_override.py +12 -0
- kiapi/capabilities/ideogram4/_operations/resolve_generate_params.py +30 -0
- kiapi/capabilities/ideogram4/_settings.py +89 -0
- kiapi/capabilities/ideogram4/_views/generate_params.py +27 -0
- kiapi/capabilities/ideogram4/_views/generate_request.py +118 -0
- kiapi/capabilities/ltx2/README.ja.md +287 -0
- kiapi/capabilities/ltx2/README.md +274 -0
- kiapi/capabilities/ltx2/__init__.py +26 -0
- kiapi/capabilities/ltx2/_constants/description.py +81 -0
- kiapi/capabilities/ltx2/_helpers/register.py +58 -0
- kiapi/capabilities/ltx2/_helpers/validate_generate.py +42 -0
- kiapi/capabilities/ltx2/_models/ltx2.py +106 -0
- kiapi/capabilities/ltx2/_operations/detect_mode.py +19 -0
- kiapi/capabilities/ltx2/_operations/handle_generate.py +52 -0
- kiapi/capabilities/ltx2/_operations/resolve_generate_params.py +31 -0
- kiapi/capabilities/ltx2/_settings.py +93 -0
- kiapi/capabilities/ltx2/_views/generate_params.py +34 -0
- kiapi/capabilities/ltx2/_views/generate_request.py +151 -0
- kiapi/capabilities/qwen/README.ja.md +251 -0
- kiapi/capabilities/qwen/README.md +235 -0
- kiapi/capabilities/qwen/__init__.py +30 -0
- kiapi/capabilities/qwen/_constants/description.py +53 -0
- kiapi/capabilities/qwen/_helpers/register.py +60 -0
- kiapi/capabilities/qwen/_helpers/validate_edit.py +12 -0
- kiapi/capabilities/qwen/_helpers/validate_generate.py +12 -0
- kiapi/capabilities/qwen/_models/qwen.py +224 -0
- kiapi/capabilities/qwen/_operations/handle_edit.py +44 -0
- kiapi/capabilities/qwen/_operations/handle_generate.py +46 -0
- kiapi/capabilities/qwen/_operations/is_quantize_override.py +15 -0
- kiapi/capabilities/qwen/_operations/resolve_edit_params.py +35 -0
- kiapi/capabilities/qwen/_operations/resolve_generate_params.py +39 -0
- kiapi/capabilities/qwen/_operations/resolve_lora_params.py +23 -0
- kiapi/capabilities/qwen/_operations/validate_common.py +32 -0
- kiapi/capabilities/qwen/_schemas/lora_ref.py +27 -0
- kiapi/capabilities/qwen/_settings.py +107 -0
- kiapi/capabilities/qwen/_views/edit_params.py +36 -0
- kiapi/capabilities/qwen/_views/edit_request.py +138 -0
- kiapi/capabilities/qwen/_views/generate_params.py +37 -0
- kiapi/capabilities/qwen/_views/generate_request.py +149 -0
- kiapi/capabilities/seedvr2/README.ja.md +234 -0
- kiapi/capabilities/seedvr2/README.md +219 -0
- kiapi/capabilities/seedvr2/__init__.py +24 -0
- kiapi/capabilities/seedvr2/_constants/description.py +46 -0
- kiapi/capabilities/seedvr2/_helpers/register.py +60 -0
- kiapi/capabilities/seedvr2/_helpers/validate_upscale.py +52 -0
- kiapi/capabilities/seedvr2/_models/seedvr2.py +140 -0
- kiapi/capabilities/seedvr2/_operations/handle_upscale.py +42 -0
- kiapi/capabilities/seedvr2/_operations/is_quantize_override.py +12 -0
- kiapi/capabilities/seedvr2/_operations/resolve_upscale_params.py +30 -0
- kiapi/capabilities/seedvr2/_settings.py +74 -0
- kiapi/capabilities/seedvr2/_views/upscale_params.py +27 -0
- kiapi/capabilities/seedvr2/_views/upscale_request.py +94 -0
- kiapi/capabilities/web/README.ja.md +187 -0
- kiapi/capabilities/web/README.md +171 -0
- kiapi/capabilities/web/__init__.py +30 -0
- kiapi/capabilities/web/_constants/description.py +38 -0
- kiapi/capabilities/web/_exceptions/FetchError.py +24 -0
- kiapi/capabilities/web/_exceptions/SearchBackendError.py +11 -0
- kiapi/capabilities/web/_helpers/register.py +59 -0
- kiapi/capabilities/web/_models/crawl4ai.py +32 -0
- kiapi/capabilities/web/_models/searxng.py +44 -0
- kiapi/capabilities/web/_operations/handle_fetch.py +145 -0
- kiapi/capabilities/web/_operations/handle_search.py +56 -0
- kiapi/capabilities/web/_operations/resolve_fetch_params.py +19 -0
- kiapi/capabilities/web/_operations/resolve_search_params.py +34 -0
- kiapi/capabilities/web/_operations/resolve_searxng_config_dir.py +21 -0
- kiapi/capabilities/web/_services/__init__.py +1 -0
- kiapi/capabilities/web/_services/web_backend_process.py +144 -0
- kiapi/capabilities/web/_settings.py +138 -0
- kiapi/capabilities/web/_views/fetch_params.py +27 -0
- kiapi/capabilities/web/_views/fetch_request.py +29 -0
- kiapi/capabilities/web/_views/fetch_result.py +20 -0
- kiapi/capabilities/web/_views/search_params.py +43 -0
- kiapi/capabilities/web/_views/search_request.py +93 -0
- kiapi/capabilities/web/_views/search_response.py +49 -0
- kiapi/capabilities/web/resources/__init__.py +0 -0
- kiapi/capabilities/web/resources/searxng/__init__.py +0 -0
- kiapi/capabilities/web/resources/searxng/settings.yml +11 -0
- kiapi/capabilities/zimage/README.ja.md +249 -0
- kiapi/capabilities/zimage/README.md +231 -0
- kiapi/capabilities/zimage/__init__.py +34 -0
- kiapi/capabilities/zimage/_constants/description.py +73 -0
- kiapi/capabilities/zimage/_helpers/register.py +62 -0
- kiapi/capabilities/zimage/_helpers/validate_generate.py +37 -0
- kiapi/capabilities/zimage/_models/zimage.py +278 -0
- kiapi/capabilities/zimage/_operations/handle_generate.py +38 -0
- kiapi/capabilities/zimage/_operations/handle_train.py +78 -0
- kiapi/capabilities/zimage/_operations/is_quantize_override.py +11 -0
- kiapi/capabilities/zimage/_operations/resolve_generate_params.py +39 -0
- kiapi/capabilities/zimage/_operations/resolve_lora_params.py +23 -0
- kiapi/capabilities/zimage/_operations/resolve_train_params.py +38 -0
- kiapi/capabilities/zimage/_schemas/lora_ref.py +27 -0
- kiapi/capabilities/zimage/_settings.py +166 -0
- kiapi/capabilities/zimage/_views/generate_params.py +23 -0
- kiapi/capabilities/zimage/_views/generate_request.py +127 -0
- kiapi/capabilities/zimage/_views/train_params.py +22 -0
- kiapi/capabilities/zimage/_views/train_request.py +101 -0
- kiapi/cli/__init__.py +11 -0
- kiapi/cli/_helpers/dedupe_resources.py +12 -0
- kiapi/cli/_helpers/register_all_capabilities.py +36 -0
- kiapi/cli/_helpers/run_resources.py +24 -0
- kiapi/cli/_helpers/select_specs.py +67 -0
- kiapi/cli/activate/_operations/preflight_hf_access.py +129 -0
- kiapi/cli/activate/cli.py +37 -0
- kiapi/cli/check/_helpers/check_audio_acestep_turbo.py +22 -0
- kiapi/cli/check/_helpers/check_audio_acestep_xl_base.py +22 -0
- kiapi/cli/check/_helpers/check_audio_audiogen_medium.py +24 -0
- kiapi/cli/check/_helpers/check_chat_chat_qwen3_6_27b.py +19 -0
- kiapi/cli/check/_helpers/check_chat_chat_qwen3_omni.py +19 -0
- kiapi/cli/check/_helpers/check_embedding_embedding_qwen3_embedding_8b.py +14 -0
- kiapi/cli/check/_helpers/check_embedding_embedding_qwen3_vl_embedding_2b.py +19 -0
- kiapi/cli/check/_helpers/check_image_depthpro_base.py +21 -0
- kiapi/cli/check/_helpers/check_image_ernie_base.py +23 -0
- kiapi/cli/check/_helpers/check_image_ernie_turbo.py +23 -0
- kiapi/cli/check/_helpers/check_image_flux2_klein_9b.py +23 -0
- kiapi/cli/check/_helpers/check_image_flux2_klein_base_4b.py +23 -0
- kiapi/cli/check/_helpers/check_image_flux2_klein_base_9b.py +23 -0
- kiapi/cli/check/_helpers/check_image_ideogram4_fp8.py +23 -0
- kiapi/cli/check/_helpers/check_image_qwen_edit_2509.py +27 -0
- kiapi/cli/check/_helpers/check_image_qwen_image.py +23 -0
- kiapi/cli/check/_helpers/check_image_seedvr2_3b.py +23 -0
- kiapi/cli/check/_helpers/check_image_seedvr2_7b.py +23 -0
- kiapi/cli/check/_helpers/check_image_zimage_base.py +23 -0
- kiapi/cli/check/_helpers/check_image_zimage_turbo.py +23 -0
- kiapi/cli/check/_helpers/check_video_ltx2_distilled.py +26 -0
- kiapi/cli/check/_helpers/check_web_web_fetch.py +14 -0
- kiapi/cli/check/_helpers/check_web_web_search.py +14 -0
- kiapi/cli/check/_operations/build_check_result.py +20 -0
- kiapi/cli/check/_operations/check_context.py +10 -0
- kiapi/cli/check/_operations/create_sample_image.py +46 -0
- kiapi/cli/check/_schemas/check_result.py +12 -0
- kiapi/cli/check/cli.py +89 -0
- kiapi/cli/cli.py +29 -0
- kiapi/cli/config/cli.py +17 -0
- kiapi/cli/config/edit/cli.py +32 -0
- kiapi/cli/config/init/cli.py +33 -0
- kiapi/cli/config/show/cli.py +13 -0
- kiapi/cli/config/template/cli.py +36 -0
- kiapi/cli/deactivate/cli.py +49 -0
- kiapi/cli/run/asgi.py +16 -0
- kiapi/cli/run/cli.py +59 -0
- kiapi/cli/service/__init__.py +5 -0
- kiapi/cli/service/_services/service_manager.py +107 -0
- kiapi/cli/service/cli.py +19 -0
- kiapi/cli/service/install/cli.py +17 -0
- kiapi/cli/service/start/cli.py +22 -0
- kiapi/cli/service/status/cli.py +81 -0
- kiapi/cli/service/stop/cli.py +19 -0
- kiapi/cli/service/uninstall/cli.py +16 -0
- kiapi/cli/status/cli.py +226 -0
- kiapi/core/app/__init__.py +16 -0
- kiapi/core/app/_schemas/app_context.py +28 -0
- kiapi/core/app/_services/user_directory.py +59 -0
- kiapi/core/app/_settings.py +46 -0
- kiapi/core/capability/__init__.py +11 -0
- kiapi/core/capability/_schemas/capability_spec.py +17 -0
- kiapi/core/capability/_services/capability_spec_registry.py +21 -0
- kiapi/core/config/__init__.py +11 -0
- kiapi/core/config/_exceptions/user_config_error.py +2 -0
- kiapi/core/config/_helpers/get_user_settings_path.py +7 -0
- kiapi/core/config/_helpers/load_user_settings.py +54 -0
- kiapi/core/file/__init__.py +37 -0
- kiapi/core/file/_helpers/create_file_store.py +7 -0
- kiapi/core/file/_helpers/resolve_file_ref.py +90 -0
- kiapi/core/file/_schemas/file_data_url_ref.py +19 -0
- kiapi/core/file/_schemas/file_id_ref.py +16 -0
- kiapi/core/file/_schemas/file_record.py +46 -0
- kiapi/core/file/_schemas/file_url_ref.py +16 -0
- kiapi/core/file/_services/file_store.py +138 -0
- kiapi/core/file/_settings.py +22 -0
- kiapi/core/file/_types/file_id.py +2 -0
- kiapi/core/file/_types/file_ref.py +12 -0
- kiapi/core/file/_views/resolved_file_ref.py +16 -0
- kiapi/core/job/__init__.py +24 -0
- kiapi/core/job/_enums/job_status.py +9 -0
- kiapi/core/job/_helpers/creep_progress.py +123 -0
- kiapi/core/job/_models/job.py +121 -0
- kiapi/core/job/_services/job_store.py +33 -0
- kiapi/core/job/_services/progress_reporter.py +79 -0
- kiapi/core/job/_types/job_id.py +3 -0
- kiapi/core/job/_types/job_result.py +5 -0
- kiapi/core/job/_types/job_type.py +4 -0
- kiapi/core/logging/__init__.py +14 -0
- kiapi/core/logging/_helpers/get_log_level.py +8 -0
- kiapi/core/logging/_helpers/setup_logger.py +14 -0
- kiapi/core/logging/_settings.py +34 -0
- kiapi/core/logging/_types/log_level.py +3 -0
- kiapi/core/memory/__init__.py +21 -0
- kiapi/core/memory/_exceptions/memory_budget_error.py +2 -0
- kiapi/core/memory/_helpers/create_memory_manager.py +17 -0
- kiapi/core/memory/_operations/log_memory_limit.py +29 -0
- kiapi/core/memory/_operations/resolve_effective_memory_limit_gb.py +13 -0
- kiapi/core/memory/_operations/resolve_framework_strategy.py +42 -0
- kiapi/core/memory/_schemas/framework_strategy.py +14 -0
- kiapi/core/memory/_schemas/memory_stats.py +24 -0
- kiapi/core/memory/_schemas/resident_model.py +14 -0
- kiapi/core/memory/_schemas/resident_model_stats.py +49 -0
- kiapi/core/memory/_services/memory_manager.py +257 -0
- kiapi/core/memory/_settings.py +36 -0
- kiapi/core/memory/_types/framework_name.py +4 -0
- kiapi/core/memory/_types/resident_key.py +4 -0
- kiapi/core/model/__init__.py +36 -0
- kiapi/core/model/_exceptions/unknown_model_error.py +2 -0
- kiapi/core/model/_schemas/model_spec.py +145 -0
- kiapi/core/model/_services/model_registry.py +85 -0
- kiapi/core/model/_types/model_alias.py +2 -0
- kiapi/core/model/_types/model_domain.py +6 -0
- kiapi/core/model/_types/model_family.py +5 -0
- kiapi/core/model/_types/model_key.py +8 -0
- kiapi/core/model/_types/model_name.py +4 -0
- kiapi/core/model/_types/model_repo.py +3 -0
- kiapi/core/net/__init__.py +16 -0
- kiapi/core/net/_exceptions/unsafe_url_error.py +7 -0
- kiapi/core/net/_helpers/verify_public_url.py +68 -0
- kiapi/core/net/_settings.py +28 -0
- kiapi/core/setup/__init__.py +25 -0
- kiapi/core/setup/_exceptions/setup_required_error.py +2 -0
- kiapi/core/setup/_schemas/docker_image_resource.py +37 -0
- kiapi/core/setup/_schemas/hf_snapshot_resource.py +50 -0
- kiapi/core/setup/_schemas/local_path_resource.py +43 -0
- kiapi/core/setup/_schemas/python_package_resource.py +58 -0
- kiapi/core/setup/_schemas/python_venv_resource.py +63 -0
- kiapi/core/setup/_schemas/setup_status.py +7 -0
- kiapi/core/setup/_schemas/url_file_resource.py +43 -0
- kiapi/core/setup/_services/setup_manager.py +331 -0
- kiapi/core/setup/_types/setup_resource.py +21 -0
- kiapi/core/setup/_types/setup_target.py +11 -0
- kiapi/core/workdir/__init__.py +8 -0
- kiapi/core/workdir/_helpers/create_work_dir.py +11 -0
- kiapi/core/workdir/_settings.py +21 -0
- kiapi/core/worker/__init__.py +23 -0
- kiapi/core/worker/_helpers/create_worker.py +9 -0
- kiapi/core/worker/_services/worker.py +165 -0
- kiapi/core/worker/_settings.py +36 -0
- kiapi/core/worker/_types/job_thunk.py +6 -0
- kiapi-0.1.0.dist-info/METADATA +337 -0
- kiapi-0.1.0.dist-info/RECORD +465 -0
- kiapi-0.1.0.dist-info/WHEEL +4 -0
- kiapi-0.1.0.dist-info/entry_points.txt +2 -0
- kiapi-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# qwen
|
|
2
|
+
|
|
3
|
+
**English** | [日本語](README.ja.md)
|
|
4
|
+
|
|
5
|
+
[mflux Qwen Image](https://github.com/filipstrand/mflux/blob/main/src/mflux/models/qwen/README.md) provides image generation and image editing functions.
|
|
6
|
+
Qwen Image is a strong model for multilingual prompts and text in images.
|
|
7
|
+
|
|
8
|
+
- **generate**:
|
|
9
|
+
- Generate images from text
|
|
10
|
+
- img2img if you pass `init_image` FileRef
|
|
11
|
+
- **edit**:
|
|
12
|
+
- Natural language editing using one or more reference images from the Files API
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
## API
|
|
16
|
+
|
|
17
|
+
| Endpoint | Name | Description |
|
|
18
|
+
|---|---|---|
|
|
19
|
+
| `POST /v1/image/qwen/generate` | Image generation | Generate image from prompt and reference image. |
|
|
20
|
+
| `POST /v1/image/qwen/edit` | Image editing | Generate an image from multiple reference images. |
|
|
21
|
+
| `GET /v1/image/qwen/models` | Model list | Returns a list of available models. |
|
|
22
|
+
| `GET /v1/image/qwen/openapi.json` | OpenAPI | Returns detailed input/output specifications, usage, and TIPS. |
|
|
23
|
+
|
|
24
|
+
## API Docs
|
|
25
|
+
|
|
26
|
+
- [OpenAPI JSON](https://kiarina.github.io/kiapi/v1/image/qwen/openapi.json)
|
|
27
|
+
- [Swagger UI](https://kiarina.github.io/kiapi/v1/image/qwen/docs.html)
|
|
28
|
+
- [ReDoc](https://kiarina.github.io/kiapi/v1/image/qwen/redoc.html)
|
|
29
|
+
|
|
30
|
+
## Dependencies
|
|
31
|
+
|
|
32
|
+
| Package | License | Description |
|
|
33
|
+
|---|---|---|
|
|
34
|
+
| [mflux](https://github.com/filipstrand/mflux) | MIT | Run Qwen Image / Qwen Image Edit on MLX. |
|
|
35
|
+
|
|
36
|
+
## Models
|
|
37
|
+
|
|
38
|
+
| Model | License | Terms | Size | Description |
|
|
39
|
+
|---|---|---|---:|---|
|
|
40
|
+
| [Qwen/Qwen-Image](https://huggingface.co/Qwen/Qwen-Image) | Apache-2.0 | Not required | 58 GB | `image` (default). Used with `generate`. txt2img/img2img. Defaults are `steps: 30`, `guidance: 4.0`, `quantize: 8`. |
|
|
41
|
+
| [Qwen/Qwen-Image-Edit-2509](https://huggingface.co/Qwen/Qwen-Image-Edit-2509) | Apache-2.0 | Not required | 58 GB | `edit-2509`. Used with `edit`. Single/multiple reference image editing. Defaults are `steps: 30`, `guidance: 2.5`, `quantize: 8`. |
|
|
42
|
+
|
|
43
|
+
`POST /v1/image/qwen/generate` is only `image`, `POST /v1/image/qwen/edit` is
|
|
44
|
+
Only `edit-2509` is accepted. Defaults for each endpoint are compensated on the router side
|
|
45
|
+
Therefore, `model` can usually be omitted.
|
|
46
|
+
|
|
47
|
+
## Notes
|
|
48
|
+
|
|
49
|
+
- **Image size**:
|
|
50
|
+
`width` / `height` are multiples of 16. Default is `1024 x 1024`, upper limit is `2048 x 2048`.
|
|
51
|
+
- **steps/guidance**:
|
|
52
|
+
`steps` is `1..100`. If omitted, both generate/edit are `30`. `guidance` is generated by
|
|
53
|
+
`4.0`, edit is `2.5`.
|
|
54
|
+
- **quantize**:
|
|
55
|
+
Default is `8`. If you want to overwrite, you can specify `3` / `4` / `5` / `6` / `8`.
|
|
56
|
+
If omitted or passed `null`, the default value will be used.
|
|
57
|
+
- **LoRA applied**:
|
|
58
|
+
Apply the adapter with `loras: [{"file": {"type": "file_id", "file_id": "..."}, "scale": 1.0}]`. Up to 4.
|
|
59
|
+
Adapter files must be stored in the Files API.
|
|
60
|
+
- **transient model**:
|
|
61
|
+
mflux fixes the quantization level and LoRA during model construction, so if you have `loras` or
|
|
62
|
+
A request to override `quantize` from its default value builds a temporary model for that call.
|
|
63
|
+
It is slower than a plain `image` / `edit-2509` call because it does not reuse the resident model.
|
|
64
|
+
- **Output format**:
|
|
65
|
+
`format` is `png` (default) / `jpeg` / `webp`. `quality` for `jpeg` / `webp`
|
|
66
|
+
Use `1..100` (default `90`).
|
|
67
|
+
- **Memory guideline**:
|
|
68
|
+
`image` / `edit-2509` are both large models. The registered value of kiapi has a weight of approximately
|
|
69
|
+
Expected to be `22.0 GiB`, with runtime headroom of approximately `8.0 GiB`.
|
|
70
|
+
|
|
71
|
+
## Quickstart
|
|
72
|
+
|
|
73
|
+
### generate - generate image from text
|
|
74
|
+
|
|
75
|
+
Save only the image:
|
|
76
|
+
```bash
|
|
77
|
+
PARAMS=$(
|
|
78
|
+
jq -n \
|
|
79
|
+
--arg prompt "a cafe storefront, a wooden sign clearly reads カフェ, bright daylight" \
|
|
80
|
+
--arg negative_prompt "blurry, low quality, distorted text" \
|
|
81
|
+
'{
|
|
82
|
+
model: "image",
|
|
83
|
+
mode: "sync",
|
|
84
|
+
prompt: $prompt,
|
|
85
|
+
negative_prompt: $negative_prompt,
|
|
86
|
+
width: 512,
|
|
87
|
+
height: 512,
|
|
88
|
+
seed: 1
|
|
89
|
+
}'
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
curl -sS -X POST http://localhost:${PORT:-8000}/v1/image/qwen/generate \
|
|
93
|
+
-H 'Content-Type: application/json' \
|
|
94
|
+
--data-binary "$PARAMS" \
|
|
95
|
+
-o qwen.png
|
|
96
|
+
```
|
|
97
|
+
Returns Job JSON:
|
|
98
|
+
```bash
|
|
99
|
+
PARAMS=$(
|
|
100
|
+
jq -n \
|
|
101
|
+
--arg prompt "a clean product label design, the main text reads KIAPI, white background" \
|
|
102
|
+
'{
|
|
103
|
+
mode: "sync",
|
|
104
|
+
prompt: $prompt,
|
|
105
|
+
width: 512,
|
|
106
|
+
height: 512,
|
|
107
|
+
seed: 2
|
|
108
|
+
}'
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
curl -sS -X POST http://localhost:${PORT:-8000}/v1/image/qwen/generate \
|
|
112
|
+
-H 'Accept: application/json' \
|
|
113
|
+
-H 'Content-Type: application/json' \
|
|
114
|
+
--data-binary "$PARAMS" |
|
|
115
|
+
jq .
|
|
116
|
+
```
|
|
117
|
+
### generate - img2img
|
|
118
|
+
|
|
119
|
+
Upload the source image first.
|
|
120
|
+
```bash
|
|
121
|
+
IMG=$(curl -sS -X POST http://localhost:${PORT:-8000}/v1/files \
|
|
122
|
+
-F "file=@source.png" | jq -r .file_id)
|
|
123
|
+
```
|
|
124
|
+
Generate based on the uploaded image.
|
|
125
|
+
```bash
|
|
126
|
+
PARAMS=$(
|
|
127
|
+
jq -n \
|
|
128
|
+
--arg img "$IMG" \
|
|
129
|
+
--arg prompt "turn this into a polished cozy illustration" \
|
|
130
|
+
'{
|
|
131
|
+
model: "image",
|
|
132
|
+
mode: "sync",
|
|
133
|
+
prompt: $prompt,
|
|
134
|
+
init_image: {type: "file_id", file_id: $img},
|
|
135
|
+
image_strength: 0.45,
|
|
136
|
+
width: 1024,
|
|
137
|
+
height: 576,
|
|
138
|
+
seed: 7
|
|
139
|
+
}'
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
curl -sS -X POST http://localhost:${PORT:-8000}/v1/image/qwen/generate \
|
|
143
|
+
-H 'Content-Type: application/json' \
|
|
144
|
+
--data-binary "$PARAMS" \
|
|
145
|
+
-o qwen-img2img.png
|
|
146
|
+
```
|
|
147
|
+
`image_strength` is `0..1`. The smaller the value, the stronger the input image will remain, and the larger the value, the stronger the prompt side.
|
|
148
|
+
The changes will become stronger.
|
|
149
|
+
|
|
150
|
+
### edit - Edit single/multiple images
|
|
151
|
+
```bash
|
|
152
|
+
REF1=$(curl -sS -X POST http://localhost:${PORT:-8000}/v1/files \
|
|
153
|
+
-F "file=@mascot.png" | jq -r .file_id)
|
|
154
|
+
REF2=$(curl -sS -X POST http://localhost:${PORT:-8000}/v1/files \
|
|
155
|
+
-F "file=@object.png" | jq -r .file_id)
|
|
156
|
+
|
|
157
|
+
PARAMS=$(
|
|
158
|
+
jq -n \
|
|
159
|
+
--arg ref1 "$REF1" \
|
|
160
|
+
--arg ref2 "$REF2" \
|
|
161
|
+
--arg prompt "combine the mascot and object into a bright product key visual; keep the mascot recognizable" \
|
|
162
|
+
'{
|
|
163
|
+
model: "edit-2509",
|
|
164
|
+
mode: "sync",
|
|
165
|
+
prompt: $prompt,
|
|
166
|
+
images: [{type: "file_id", file_id: $ref1}, {type: "file_id", file_id: $ref2}],
|
|
167
|
+
width: 1024,
|
|
168
|
+
height: 576,
|
|
169
|
+
seed: 9
|
|
170
|
+
}'
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
curl -sS -X POST http://localhost:${PORT:-8000}/v1/image/qwen/edit \
|
|
174
|
+
-H 'Content-Type: application/json' \
|
|
175
|
+
--data-binary "$PARAMS" \
|
|
176
|
+
-o qwen-edit.png
|
|
177
|
+
```
|
|
178
|
+
`images` is one or more. For editing a single image or for compositing and reconstructing using multiple reference images.
|
|
179
|
+
You can use it.
|
|
180
|
+
|
|
181
|
+
###async
|
|
182
|
+
```bash
|
|
183
|
+
PARAMS=$(
|
|
184
|
+
jq -n \
|
|
185
|
+
--arg prompt "a typography poster, large readable text says LOCAL AI" \
|
|
186
|
+
'{
|
|
187
|
+
mode: "async",
|
|
188
|
+
prompt: $prompt,
|
|
189
|
+
width: 512,
|
|
190
|
+
height: 512,
|
|
191
|
+
seed: 11
|
|
192
|
+
}'
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
JOB=$(curl -sS -X POST http://localhost:${PORT:-8000}/v1/image/qwen/generate \
|
|
196
|
+
-H 'Accept: application/json' \
|
|
197
|
+
-H 'Content-Type: application/json' \
|
|
198
|
+
--data-binary "$PARAMS" |
|
|
199
|
+
jq -r .job_id)
|
|
200
|
+
|
|
201
|
+
curl -sS http://localhost:${PORT:-8000}/v1/jobs/$JOB | jq .
|
|
202
|
+
```
|
|
203
|
+
After completion, use the Job's `artifacts[0]` or `result.file_id` to get the image.
|
|
204
|
+
```bash
|
|
205
|
+
FID=$(curl -sS http://localhost:${PORT:-8000}/v1/jobs/$JOB | jq -r .result.file_id)
|
|
206
|
+
curl -sS http://localhost:${PORT:-8000}/v1/files/$FID/download -o qwen-async.png
|
|
207
|
+
```
|
|
208
|
+
### Generated by applying LoRA
|
|
209
|
+
|
|
210
|
+
Upload `.safetensors`, such as learned adapters, to the Files API and reference them with `loras`.
|
|
211
|
+
```bash
|
|
212
|
+
ADAPTER=$(curl -sS -X POST http://localhost:${PORT:-8000}/v1/files \
|
|
213
|
+
-F "file=@adapter.safetensors" | jq -r .file_id)
|
|
214
|
+
|
|
215
|
+
PARAMS=$(
|
|
216
|
+
jq -n \
|
|
217
|
+
--arg adapter "$ADAPTER" \
|
|
218
|
+
--arg prompt "<your trigger word> as a clean editorial illustration" \
|
|
219
|
+
'{
|
|
220
|
+
model: "image",
|
|
221
|
+
mode: "sync",
|
|
222
|
+
prompt: $prompt,
|
|
223
|
+
width: 512,
|
|
224
|
+
height: 512,
|
|
225
|
+
seed: 13,
|
|
226
|
+
loras: [{file: {type: "file_id", file_id: $adapter}, scale: 1.0}]
|
|
227
|
+
}'
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
curl -sS -X POST http://localhost:${PORT:-8000}/v1/image/qwen/generate \
|
|
231
|
+
-H 'Content-Type: application/json' \
|
|
232
|
+
--data-binary "$PARAMS" \
|
|
233
|
+
-o qwen-lora.png
|
|
234
|
+
```
|
|
235
|
+
`scale` is the strength of the effect. Every request using `loras` builds a temporary model.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""qwen family — Qwen Image generation/editing via mflux.
|
|
2
|
+
|
|
3
|
+
Endpoints: ``POST /v1/image/qwen/{generate,edit}``. ``generate`` is txt2img by
|
|
4
|
+
default and img2img when ``init_image_file_id`` is supplied; ``edit`` does
|
|
5
|
+
natural-language single/multi-image editing. LoRA adapters and a ``quantize``
|
|
6
|
+
override run on a one-off transient model; otherwise the resident model is used.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from kiapi.capabilities import ValidationError
|
|
10
|
+
|
|
11
|
+
from ._helpers.register import register
|
|
12
|
+
from ._helpers.validate_edit import validate_edit
|
|
13
|
+
from ._helpers.validate_generate import validate_generate
|
|
14
|
+
from ._operations.handle_edit import handle_edit
|
|
15
|
+
from ._operations.handle_generate import handle_generate
|
|
16
|
+
from ._settings import settings_manager
|
|
17
|
+
from ._views.edit_request import EditRequest
|
|
18
|
+
from ._views.generate_request import GenerateRequest
|
|
19
|
+
|
|
20
|
+
__all__ = [
|
|
21
|
+
"EditRequest", # ._views
|
|
22
|
+
"GenerateRequest", # ._views
|
|
23
|
+
"ValidationError", # kiapi.capabilities
|
|
24
|
+
"handle_edit", # ._operations
|
|
25
|
+
"handle_generate", # ._operations
|
|
26
|
+
"register", # ._helpers
|
|
27
|
+
"settings_manager", # ._settings
|
|
28
|
+
"validate_edit", # ._helpers
|
|
29
|
+
"validate_generate", # ._helpers
|
|
30
|
+
]
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
DESCRIPTION = """Image generation and editing (Qwen-Image via mflux).
|
|
2
|
+
|
|
3
|
+
Two operations on Alibaba's Qwen-Image models: `/generate` (text-to-image, or
|
|
4
|
+
image-to-image when `init_image` is supplied) and `/edit` (natural-language
|
|
5
|
+
single/multi-image editing). Qwen-Image is strong at rendered text and
|
|
6
|
+
instruction-following edits.
|
|
7
|
+
|
|
8
|
+
## Upstream docs
|
|
9
|
+
- [mflux — Qwen Image](https://github.com/filipstrand/mflux/blob/main/src/mflux/models/qwen/README.md) — the MLX engine kiapi runs
|
|
10
|
+
- [Qwen/Qwen-Image](https://huggingface.co/Qwen/Qwen-Image) — generate weights
|
|
11
|
+
- [Qwen/Qwen-Image-Edit-2509](https://huggingface.co/Qwen/Qwen-Image-Edit-2509) — edit weights
|
|
12
|
+
|
|
13
|
+
## Models
|
|
14
|
+
- **image** (default) — text-to-image / img2img. The only variant `/generate`
|
|
15
|
+
accepts.
|
|
16
|
+
- **edit-2509** — instruction-based editing. The only variant `/edit` accepts.
|
|
17
|
+
|
|
18
|
+
Each endpoint is pinned to its variant, so `model` is effectively fixed per
|
|
19
|
+
operation; discover variants at `GET /v1/image/qwen/models`. Omitted
|
|
20
|
+
`steps`/`guidance`/`quantize`/size are filled in server-side and the resolved
|
|
21
|
+
values are recorded in the result `params`.
|
|
22
|
+
|
|
23
|
+
## generate vs edit
|
|
24
|
+
- **generate** is text-to-image; pass `init_image` (+ optional `image_strength`
|
|
25
|
+
in 0..1) to seed an img2img run from one image.
|
|
26
|
+
- **edit** takes a list of reference `images` for single- or multi-image editing
|
|
27
|
+
/ composition under one natural-language prompt.
|
|
28
|
+
|
|
29
|
+
## Resident vs transient runs
|
|
30
|
+
The warmed, resident model uses the server-default quantization (q8). A request
|
|
31
|
+
that either supplies `loras` or sets a `quantize` differing from the resident
|
|
32
|
+
model builds a **one-off transient model** for that call — weights load fresh, so
|
|
33
|
+
it is slower and not reused. For the fast path, omit `loras` and leave `quantize`
|
|
34
|
+
unset.
|
|
35
|
+
|
|
36
|
+
## LoRA
|
|
37
|
+
Apply adapters by passing their `file` ids in `loras` (up to 4, each
|
|
38
|
+
`{file, scale}`). Any lora forces a transient run.
|
|
39
|
+
|
|
40
|
+
## TIPS
|
|
41
|
+
- For a quick image, call `sync` without `Accept: application/json` to get the
|
|
42
|
+
raw bytes straight back (`curl -o out.png`).
|
|
43
|
+
- `width`/`height` must be multiples of 16 and at most 2048x2048 (default 1024).
|
|
44
|
+
- Qwen-Image renders legible text well — describe the wanted text explicitly in
|
|
45
|
+
the prompt.
|
|
46
|
+
- First use downloads the Qwen weights (~58 GB full); run `kiapi activate` ahead
|
|
47
|
+
of time to avoid a cold-start download on the first request.
|
|
48
|
+
|
|
49
|
+
## Performance
|
|
50
|
+
- Upstream weights are large (~58 GB full); kiapi defaults to q8.
|
|
51
|
+
- Transient runs (any `loras` or a `quantize` override) rebuild the model each
|
|
52
|
+
call and are slower than the resident path.
|
|
53
|
+
"""
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""Register qwen's models + OpenAPI description in the global registries."""
|
|
2
|
+
|
|
3
|
+
from kiapi.core.capability import CapabilitySpec, capability_spec_registry
|
|
4
|
+
from kiapi.core.model import ModelSpec, model_registry
|
|
5
|
+
from kiapi.core.setup import HfSnapshotResource
|
|
6
|
+
|
|
7
|
+
from .._constants.description import DESCRIPTION
|
|
8
|
+
from .._models import qwen
|
|
9
|
+
from .._settings import settings_manager
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def register() -> None:
|
|
13
|
+
capability_spec_registry.register(
|
|
14
|
+
CapabilitySpec(
|
|
15
|
+
name="qwen",
|
|
16
|
+
domain="image",
|
|
17
|
+
title="kiapi Qwen Image API",
|
|
18
|
+
summary="Generate and edit images with Qwen Image models.",
|
|
19
|
+
description=DESCRIPTION,
|
|
20
|
+
openapi_path="/v1/image/qwen/openapi.json",
|
|
21
|
+
docs_path="/v1/image/qwen/docs",
|
|
22
|
+
redoc_path="/v1/image/qwen/redoc",
|
|
23
|
+
path_prefixes=("/v1/image/qwen",),
|
|
24
|
+
)
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
_s = settings_manager.get_settings()
|
|
28
|
+
|
|
29
|
+
model_registry.register(
|
|
30
|
+
ModelSpec(
|
|
31
|
+
name="image",
|
|
32
|
+
family="qwen",
|
|
33
|
+
domain="image",
|
|
34
|
+
repo=_s.image_model,
|
|
35
|
+
module=qwen,
|
|
36
|
+
weight_gb=22.0,
|
|
37
|
+
peak_headroom_gb=8.0,
|
|
38
|
+
framework="mlx",
|
|
39
|
+
priority=0,
|
|
40
|
+
aliases=("qwen-image", "Qwen/Qwen-Image"),
|
|
41
|
+
default=True,
|
|
42
|
+
setup_resources=(HfSnapshotResource(repo=_s.image_model, disk_gb=58.0),),
|
|
43
|
+
)
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
model_registry.register(
|
|
47
|
+
ModelSpec(
|
|
48
|
+
name="edit-2509",
|
|
49
|
+
family="qwen",
|
|
50
|
+
domain="image",
|
|
51
|
+
repo=_s.edit_model,
|
|
52
|
+
module=qwen,
|
|
53
|
+
weight_gb=22.0,
|
|
54
|
+
peak_headroom_gb=8.0,
|
|
55
|
+
framework="mlx",
|
|
56
|
+
priority=0,
|
|
57
|
+
aliases=("qwen-edit", "qwen-image-edit", "Qwen/Qwen-Image-Edit-2509"),
|
|
58
|
+
setup_resources=(HfSnapshotResource(repo=_s.edit_model, disk_gb=58.0),),
|
|
59
|
+
)
|
|
60
|
+
)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from kiapi.capabilities import ValidationError
|
|
2
|
+
|
|
3
|
+
from .._operations.validate_common import validate_common
|
|
4
|
+
from .._settings import settings_manager
|
|
5
|
+
from .._views.edit_request import EditRequest
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def validate_edit(req: EditRequest) -> None:
|
|
9
|
+
settings = settings_manager.get_settings()
|
|
10
|
+
validate_common(req, settings, role="edit")
|
|
11
|
+
if not req.images:
|
|
12
|
+
raise ValidationError("edit requires at least one image")
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from kiapi.capabilities import ValidationError
|
|
2
|
+
|
|
3
|
+
from .._operations.validate_common import validate_common
|
|
4
|
+
from .._settings import settings_manager
|
|
5
|
+
from .._views.generate_request import GenerateRequest
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def validate_generate(req: GenerateRequest) -> None:
|
|
9
|
+
settings = settings_manager.get_settings()
|
|
10
|
+
validate_common(req, settings, role="generate")
|
|
11
|
+
if req.image_strength is not None and not 0 <= req.image_strength <= 1:
|
|
12
|
+
raise ValidationError("image_strength must be in 0..1")
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
"""Handler for Qwen Image generate/edit via mflux."""
|
|
2
|
+
|
|
3
|
+
import gc
|
|
4
|
+
import time
|
|
5
|
+
from types import SimpleNamespace
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
from kiapi.capabilities import attach_mflux_progress
|
|
9
|
+
from kiapi.core.file import FileStore
|
|
10
|
+
from kiapi.core.model import ModelSpec
|
|
11
|
+
from kiapi.core.workdir import create_work_dir
|
|
12
|
+
|
|
13
|
+
from .._views.edit_params import EditParams
|
|
14
|
+
from .._views.generate_params import GenerateParams
|
|
15
|
+
|
|
16
|
+
FEATURES = {"text", "image"}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _role(spec: ModelSpec) -> str:
|
|
20
|
+
return "edit" if spec.name == "edit-2509" else "generate"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _build_generate_model(
|
|
24
|
+
spec: ModelSpec,
|
|
25
|
+
*,
|
|
26
|
+
quantize: int | None,
|
|
27
|
+
lora_paths: list[str] | None = None,
|
|
28
|
+
lora_scales: list[float] | None = None,
|
|
29
|
+
) -> Any:
|
|
30
|
+
from mflux.models.common.config import ModelConfig # type: ignore
|
|
31
|
+
from mflux.models.qwen.variants.txt2img.qwen_image import QwenImage # type: ignore
|
|
32
|
+
|
|
33
|
+
return QwenImage(
|
|
34
|
+
quantize=quantize,
|
|
35
|
+
model_path=spec.repo,
|
|
36
|
+
lora_paths=lora_paths or None,
|
|
37
|
+
lora_scales=lora_scales or None,
|
|
38
|
+
model_config=ModelConfig.qwen_image(),
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _build_edit_model(
|
|
43
|
+
spec: ModelSpec,
|
|
44
|
+
*,
|
|
45
|
+
quantize: int | None,
|
|
46
|
+
lora_paths: list[str] | None = None,
|
|
47
|
+
lora_scales: list[float] | None = None,
|
|
48
|
+
) -> Any:
|
|
49
|
+
from mflux.models.common.config import ModelConfig
|
|
50
|
+
from mflux.models.qwen.variants.edit.qwen_image_edit import ( # type: ignore[import-untyped]
|
|
51
|
+
QwenImageEdit,
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
return QwenImageEdit(
|
|
55
|
+
quantize=quantize,
|
|
56
|
+
model_path=spec.repo,
|
|
57
|
+
lora_paths=lora_paths or None,
|
|
58
|
+
lora_scales=lora_scales or None,
|
|
59
|
+
model_config=ModelConfig.qwen_image_edit(),
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def load(spec: ModelSpec) -> SimpleNamespace:
|
|
64
|
+
from .._settings import settings_manager
|
|
65
|
+
|
|
66
|
+
settings = settings_manager.get_settings()
|
|
67
|
+
role = _role(spec)
|
|
68
|
+
quantize = settings.default_quantize
|
|
69
|
+
model = (
|
|
70
|
+
_build_edit_model(spec, quantize=quantize)
|
|
71
|
+
if role == "edit"
|
|
72
|
+
else _build_generate_model(spec, quantize=quantize)
|
|
73
|
+
)
|
|
74
|
+
return SimpleNamespace(model=model, spec=spec, role=role, quantize=quantize)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def warmup(payload: SimpleNamespace) -> None:
|
|
78
|
+
if payload.role == "edit":
|
|
79
|
+
return
|
|
80
|
+
payload.model.generate_image(
|
|
81
|
+
seed=0, prompt="warmup", num_inference_steps=1, width=256, height=256
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _store_image(
|
|
86
|
+
image: Any,
|
|
87
|
+
*,
|
|
88
|
+
fmt: str,
|
|
89
|
+
quality: int,
|
|
90
|
+
files: FileStore,
|
|
91
|
+
meta: dict[str, Any],
|
|
92
|
+
) -> dict[str, Any]:
|
|
93
|
+
pil = getattr(image, "image", image)
|
|
94
|
+
ext = "jpg" if fmt == "jpeg" else fmt
|
|
95
|
+
tmp_dir = create_work_dir("image/qwen")
|
|
96
|
+
out_path = tmp_dir / f"image.{ext}"
|
|
97
|
+
save_kwargs: dict[str, Any] = {}
|
|
98
|
+
if fmt in ("jpeg", "webp"):
|
|
99
|
+
save_kwargs["quality"] = quality
|
|
100
|
+
if fmt == "jpeg":
|
|
101
|
+
pil = pil.convert("RGB")
|
|
102
|
+
pil.save(out_path, format=fmt.upper(), **save_kwargs)
|
|
103
|
+
if not out_path.exists():
|
|
104
|
+
raise RuntimeError("generation finished but no image file was produced")
|
|
105
|
+
rec = files.put_path(
|
|
106
|
+
out_path,
|
|
107
|
+
filename=f"qwen_{int(time.time())}.{ext}",
|
|
108
|
+
content_type=f"image/{fmt}",
|
|
109
|
+
meta=meta,
|
|
110
|
+
move=True,
|
|
111
|
+
)
|
|
112
|
+
return {"file_id": rec.file_id, "image_bytes": rec.size, **meta}
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def _generate(model: Any, params: GenerateParams, files: FileStore) -> dict[str, Any]:
|
|
116
|
+
t0 = time.time()
|
|
117
|
+
attach_mflux_progress(model)
|
|
118
|
+
image = model.generate_image(
|
|
119
|
+
seed=params.seed,
|
|
120
|
+
prompt=params.prompt,
|
|
121
|
+
negative_prompt=params.negative_prompt,
|
|
122
|
+
image_path=params.image_path,
|
|
123
|
+
image_strength=params.image_strength,
|
|
124
|
+
num_inference_steps=params.steps,
|
|
125
|
+
width=params.width,
|
|
126
|
+
height=params.height,
|
|
127
|
+
guidance=params.guidance,
|
|
128
|
+
scheduler=params.scheduler,
|
|
129
|
+
)
|
|
130
|
+
total_s = round(time.time() - t0, 2)
|
|
131
|
+
meta = {
|
|
132
|
+
"model": params.model,
|
|
133
|
+
"prompt": params.prompt,
|
|
134
|
+
"params": params.model_dump(exclude={"image_path"}),
|
|
135
|
+
"width": params.width,
|
|
136
|
+
"height": params.height,
|
|
137
|
+
"timings": {"total_s": total_s},
|
|
138
|
+
}
|
|
139
|
+
return _store_image(
|
|
140
|
+
image, fmt=params.format, quality=params.quality, files=files, meta=meta
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def _edit(model: Any, params: EditParams, files: FileStore) -> dict[str, Any]:
|
|
145
|
+
t0 = time.time()
|
|
146
|
+
attach_mflux_progress(model)
|
|
147
|
+
image = model.generate_image(
|
|
148
|
+
seed=params.seed,
|
|
149
|
+
prompt=params.prompt,
|
|
150
|
+
negative_prompt=params.negative_prompt,
|
|
151
|
+
image_paths=params.image_paths,
|
|
152
|
+
image_path=params.image_paths[0],
|
|
153
|
+
num_inference_steps=params.steps,
|
|
154
|
+
width=params.width,
|
|
155
|
+
height=params.height,
|
|
156
|
+
guidance=params.guidance,
|
|
157
|
+
scheduler=params.scheduler,
|
|
158
|
+
)
|
|
159
|
+
total_s = round(time.time() - t0, 2)
|
|
160
|
+
meta = {
|
|
161
|
+
"model": params.model,
|
|
162
|
+
"prompt": params.prompt,
|
|
163
|
+
"params": params.model_dump(exclude={"image_paths"}),
|
|
164
|
+
"width": params.width,
|
|
165
|
+
"height": params.height,
|
|
166
|
+
"timings": {"total_s": total_s},
|
|
167
|
+
}
|
|
168
|
+
return _store_image(
|
|
169
|
+
image, fmt=params.format, quality=params.quality, files=files, meta=meta
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def run_generate(
|
|
174
|
+
payload: SimpleNamespace, params: GenerateParams, files: FileStore
|
|
175
|
+
) -> dict[str, Any]:
|
|
176
|
+
return _generate(payload.model, params, files)
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def run_edit(
|
|
180
|
+
payload: SimpleNamespace, params: EditParams, files: FileStore
|
|
181
|
+
) -> dict[str, Any]:
|
|
182
|
+
return _edit(payload.model, params, files)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def run_generate_transient(
|
|
186
|
+
spec: ModelSpec,
|
|
187
|
+
params: GenerateParams,
|
|
188
|
+
files: FileStore,
|
|
189
|
+
*,
|
|
190
|
+
lora_paths: list[str],
|
|
191
|
+
lora_scales: list[float],
|
|
192
|
+
) -> dict[str, Any]:
|
|
193
|
+
model = _build_generate_model(
|
|
194
|
+
spec, quantize=params.quantize, lora_paths=lora_paths, lora_scales=lora_scales
|
|
195
|
+
)
|
|
196
|
+
try:
|
|
197
|
+
return _generate(model, params, files)
|
|
198
|
+
finally:
|
|
199
|
+
_free(model)
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def run_edit_transient(
|
|
203
|
+
spec: ModelSpec,
|
|
204
|
+
params: EditParams,
|
|
205
|
+
files: FileStore,
|
|
206
|
+
*,
|
|
207
|
+
lora_paths: list[str],
|
|
208
|
+
lora_scales: list[float],
|
|
209
|
+
) -> dict[str, Any]:
|
|
210
|
+
model = _build_edit_model(
|
|
211
|
+
spec, quantize=params.quantize, lora_paths=lora_paths, lora_scales=lora_scales
|
|
212
|
+
)
|
|
213
|
+
try:
|
|
214
|
+
return _edit(model, params, files)
|
|
215
|
+
finally:
|
|
216
|
+
_free(model)
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
def _free(model: Any) -> None:
|
|
220
|
+
del model
|
|
221
|
+
gc.collect()
|
|
222
|
+
import mlx.core as mx
|
|
223
|
+
|
|
224
|
+
mx.clear_cache()
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""Qwen Image edit service entry (worker-thread thunk body)."""
|
|
2
|
+
|
|
3
|
+
from kiapi.capabilities import CapabilityError, get_file_path
|
|
4
|
+
from kiapi.core.app import AppContext
|
|
5
|
+
from kiapi.core.file import FileID
|
|
6
|
+
from kiapi.core.job import JobResult
|
|
7
|
+
from kiapi.core.model import model_registry
|
|
8
|
+
|
|
9
|
+
from .._settings import settings_manager
|
|
10
|
+
from .._views.edit_request import EditRequest
|
|
11
|
+
from .is_quantize_override import is_quantize_override
|
|
12
|
+
from .resolve_edit_params import resolve_edit_params
|
|
13
|
+
from .resolve_lora_params import resolve_lora_params
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def handle_edit(ctx: AppContext, req: EditRequest) -> tuple[JobResult, list[FileID]]:
|
|
17
|
+
settings = settings_manager.get_settings()
|
|
18
|
+
spec = model_registry.resolve("qwen", req.model or "edit-2509")
|
|
19
|
+
ctx.ensure_model_ready(spec)
|
|
20
|
+
if spec.name != "edit-2509":
|
|
21
|
+
raise CapabilityError("qwen edit requires model 'edit-2509'")
|
|
22
|
+
image_paths = [
|
|
23
|
+
get_file_path(ctx.file_store, image, kind="image") for image in req.images
|
|
24
|
+
]
|
|
25
|
+
lora_params = resolve_lora_params(ctx, req.loras)
|
|
26
|
+
override = is_quantize_override(settings, req)
|
|
27
|
+
params = resolve_edit_params(
|
|
28
|
+
settings, req, variant=spec.name, image_paths=image_paths
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
if lora_params.paths or override:
|
|
32
|
+
ctx.memory_manager.reserve(spec.weight_gb + spec.peak_headroom_gb)
|
|
33
|
+
result = spec.module.run_edit_transient(
|
|
34
|
+
spec,
|
|
35
|
+
params,
|
|
36
|
+
ctx.file_store,
|
|
37
|
+
lora_paths=lora_params.paths,
|
|
38
|
+
lora_scales=lora_params.scales,
|
|
39
|
+
)
|
|
40
|
+
else:
|
|
41
|
+
payload = ctx.memory_manager.acquire(spec)
|
|
42
|
+
result = spec.module.run_edit(payload, params, ctx.file_store)
|
|
43
|
+
|
|
44
|
+
return result, [result["file_id"]]
|