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,105 @@
|
|
|
1
|
+
"""FLUX.2 LoRA finetune service entry (always-async worker-thread thunk)."""
|
|
2
|
+
|
|
3
|
+
import shutil
|
|
4
|
+
import zipfile
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from kiapi.capabilities import CapabilityError, get_file_path
|
|
8
|
+
from kiapi.core.app import AppContext
|
|
9
|
+
from kiapi.core.file import FileID
|
|
10
|
+
from kiapi.core.job import JobResult
|
|
11
|
+
from kiapi.core.model import model_registry
|
|
12
|
+
from kiapi.core.workdir import create_work_dir
|
|
13
|
+
|
|
14
|
+
from .._settings import settings_manager
|
|
15
|
+
from .._views.train_request import TrainRequest
|
|
16
|
+
from .resolve_train_params import resolve_train_params
|
|
17
|
+
|
|
18
|
+
_IMAGE_EXTS = {".jpg", ".jpeg", ".png", ".webp"}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def handle_train(ctx: AppContext, req: TrainRequest) -> tuple[JobResult, list[FileID]]:
|
|
22
|
+
settings = settings_manager.get_settings()
|
|
23
|
+
spec = model_registry.resolve("flux2", req.model or settings.train_default_model)
|
|
24
|
+
ctx.ensure_model_ready(spec)
|
|
25
|
+
if "base" not in spec.name:
|
|
26
|
+
raise CapabilityError(
|
|
27
|
+
"Flux2 training requires a base variant: klein-base-4b or klein-base-9b"
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
dataset_path = get_file_path(ctx.file_store, req.dataset, kind="dataset")
|
|
31
|
+
|
|
32
|
+
workdir = create_work_dir("train/flux2")
|
|
33
|
+
try:
|
|
34
|
+
data_dir = _extract_dataset(dataset_path, workdir / "data")
|
|
35
|
+
n_images = _validate_dataset(data_dir, training_mode=req.training_mode)
|
|
36
|
+
params = resolve_train_params(settings, req, variant=spec.name)
|
|
37
|
+
ctx.memory_manager.reserve(settings.train_reserve_gb)
|
|
38
|
+
result = spec.module.train(spec, params, ctx.file_store, str(data_dir))
|
|
39
|
+
result["num_images"] = n_images
|
|
40
|
+
return result, [result["adapter_file_id"]]
|
|
41
|
+
finally:
|
|
42
|
+
shutil.rmtree(workdir, ignore_errors=True)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _extract_dataset(zip_path: str, dest: Path) -> Path:
|
|
46
|
+
dest.mkdir(parents=True, exist_ok=True)
|
|
47
|
+
with zipfile.ZipFile(zip_path) as zf:
|
|
48
|
+
for member in zf.namelist():
|
|
49
|
+
target = (dest / member).resolve()
|
|
50
|
+
if not str(target).startswith(str(dest.resolve())):
|
|
51
|
+
raise CapabilityError(f"unsafe path in dataset zip: {member!r}")
|
|
52
|
+
zf.extractall(dest)
|
|
53
|
+
|
|
54
|
+
def _has_images(d: Path) -> bool:
|
|
55
|
+
return any(p.suffix.lower() in _IMAGE_EXTS for p in d.iterdir() if p.is_file())
|
|
56
|
+
|
|
57
|
+
if _has_images(dest):
|
|
58
|
+
return dest
|
|
59
|
+
subdirs = [p for p in dest.iterdir() if p.is_dir()]
|
|
60
|
+
if len(subdirs) == 1 and _has_images(subdirs[0]):
|
|
61
|
+
return subdirs[0]
|
|
62
|
+
raise CapabilityError(
|
|
63
|
+
"dataset zip must contain images at the top level or in a single subfolder"
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _validate_dataset(data_dir: Path, *, training_mode: str) -> int:
|
|
68
|
+
images = [
|
|
69
|
+
p for p in data_dir.iterdir() if p.is_file() and p.suffix.lower() in _IMAGE_EXTS
|
|
70
|
+
]
|
|
71
|
+
if not images:
|
|
72
|
+
raise CapabilityError("dataset has no images")
|
|
73
|
+
out_images = [p for p in images if p.stem.endswith("_out")]
|
|
74
|
+
if training_mode == "edit":
|
|
75
|
+
if not out_images:
|
|
76
|
+
raise CapabilityError(
|
|
77
|
+
"edit training dataset must contain *_in / *_out image pairs"
|
|
78
|
+
)
|
|
79
|
+
count = 0
|
|
80
|
+
for out_path in out_images:
|
|
81
|
+
base = out_path.stem[:-4]
|
|
82
|
+
if not any((data_dir / f"{base}_in{ext}").exists() for ext in _IMAGE_EXTS):
|
|
83
|
+
raise CapabilityError(
|
|
84
|
+
f"missing input image for {out_path.name}: expected {base}_in.*"
|
|
85
|
+
)
|
|
86
|
+
if not (data_dir / f"{base}_in.txt").exists():
|
|
87
|
+
raise CapabilityError(
|
|
88
|
+
f"missing prompt file for {base}_in.*: expected {base}_in.txt"
|
|
89
|
+
)
|
|
90
|
+
count += 1
|
|
91
|
+
return count
|
|
92
|
+
|
|
93
|
+
if out_images:
|
|
94
|
+
raise CapabilityError(
|
|
95
|
+
"text training dataset must not use *_in / *_out edit pairs"
|
|
96
|
+
)
|
|
97
|
+
missing = [
|
|
98
|
+
p.name
|
|
99
|
+
for p in images
|
|
100
|
+
if not p.stem.startswith("preview")
|
|
101
|
+
and not (data_dir / f"{p.stem}.txt").exists()
|
|
102
|
+
]
|
|
103
|
+
if missing:
|
|
104
|
+
raise CapabilityError(f"images missing a same-stem .txt caption: {missing}")
|
|
105
|
+
return len([p for p in images if not p.stem.startswith("preview")])
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Decide whether a request's quantize differs from the variant default.
|
|
2
|
+
|
|
3
|
+
A True result means the resident model (quantized at its default) can't serve the
|
|
4
|
+
request, so ``handle_*`` runs a one-off transient model instead.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .._settings import Flux2Settings
|
|
8
|
+
from .._views.edit_request import EditRequest
|
|
9
|
+
from .._views.generate_request import GenerateRequest
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def is_quantize_override(
|
|
13
|
+
settings: Flux2Settings, req: GenerateRequest | EditRequest, *, variant: str
|
|
14
|
+
) -> bool:
|
|
15
|
+
default_quantize = settings.default_quantize.get(variant)
|
|
16
|
+
return req.quantize is not None and req.quantize != default_quantize
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""Merge an edit request with settings defaults into the complete EditParams."""
|
|
2
|
+
|
|
3
|
+
import random
|
|
4
|
+
|
|
5
|
+
from .._settings import Flux2Settings
|
|
6
|
+
from .._views.edit_params import EditParams
|
|
7
|
+
from .._views.edit_request import EditRequest
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def resolve_edit_params(
|
|
11
|
+
settings: Flux2Settings,
|
|
12
|
+
req: EditRequest,
|
|
13
|
+
*,
|
|
14
|
+
variant: str,
|
|
15
|
+
image_paths: list[str],
|
|
16
|
+
) -> EditParams:
|
|
17
|
+
return EditParams(
|
|
18
|
+
model=variant,
|
|
19
|
+
prompt=req.prompt,
|
|
20
|
+
image_file_ids=[],
|
|
21
|
+
image_paths=image_paths,
|
|
22
|
+
image_strength=req.image_strength,
|
|
23
|
+
seed=req.seed if req.seed is not None else random.randint(0, 2**31 - 1),
|
|
24
|
+
width=req.width if req.width is not None else settings.default_width,
|
|
25
|
+
height=req.height if req.height is not None else settings.default_height,
|
|
26
|
+
steps=req.steps
|
|
27
|
+
if req.steps is not None
|
|
28
|
+
else settings.default_steps.get(variant, 4),
|
|
29
|
+
guidance=(
|
|
30
|
+
req.guidance
|
|
31
|
+
if req.guidance is not None
|
|
32
|
+
else settings.default_guidance.get(variant, 1.0)
|
|
33
|
+
),
|
|
34
|
+
quantize=(
|
|
35
|
+
req.quantize
|
|
36
|
+
if req.quantize is not None
|
|
37
|
+
else settings.default_quantize.get(variant)
|
|
38
|
+
),
|
|
39
|
+
scheduler=req.scheduler,
|
|
40
|
+
format=req.format,
|
|
41
|
+
quality=req.quality,
|
|
42
|
+
loras=req.loras,
|
|
43
|
+
)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""Merge a generate request with settings defaults into the complete GenerateParams."""
|
|
2
|
+
|
|
3
|
+
import random
|
|
4
|
+
|
|
5
|
+
from .._settings import Flux2Settings
|
|
6
|
+
from .._views.generate_params import GenerateParams
|
|
7
|
+
from .._views.generate_request import GenerateRequest
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def resolve_generate_params(
|
|
11
|
+
settings: Flux2Settings,
|
|
12
|
+
req: GenerateRequest,
|
|
13
|
+
*,
|
|
14
|
+
variant: str,
|
|
15
|
+
init_image_path: str | None,
|
|
16
|
+
) -> GenerateParams:
|
|
17
|
+
return GenerateParams(
|
|
18
|
+
kind="img2img" if init_image_path else "txt2img",
|
|
19
|
+
model=variant,
|
|
20
|
+
prompt=req.prompt,
|
|
21
|
+
init_image_file_id=None,
|
|
22
|
+
init_image_path=init_image_path,
|
|
23
|
+
image_strength=req.image_strength,
|
|
24
|
+
seed=req.seed if req.seed is not None else random.randint(0, 2**31 - 1),
|
|
25
|
+
width=req.width if req.width is not None else settings.default_width,
|
|
26
|
+
height=req.height if req.height is not None else settings.default_height,
|
|
27
|
+
steps=req.steps
|
|
28
|
+
if req.steps is not None
|
|
29
|
+
else settings.default_steps.get(variant, 4),
|
|
30
|
+
guidance=(
|
|
31
|
+
req.guidance
|
|
32
|
+
if req.guidance is not None
|
|
33
|
+
else settings.default_guidance.get(variant, 1.0)
|
|
34
|
+
),
|
|
35
|
+
quantize=(
|
|
36
|
+
req.quantize
|
|
37
|
+
if req.quantize is not None
|
|
38
|
+
else settings.default_quantize.get(variant)
|
|
39
|
+
),
|
|
40
|
+
scheduler=req.scheduler,
|
|
41
|
+
format=req.format,
|
|
42
|
+
quality=req.quality,
|
|
43
|
+
loras=req.loras,
|
|
44
|
+
)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from collections.abc import Iterable
|
|
2
|
+
from dataclasses import dataclass, field
|
|
3
|
+
|
|
4
|
+
from kiapi.capabilities import get_file_path
|
|
5
|
+
from kiapi.core.app import AppContext
|
|
6
|
+
|
|
7
|
+
from .._schemas.lora_ref import LoraRef
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass
|
|
11
|
+
class LoraParams:
|
|
12
|
+
paths: list[str] = field(default_factory=list)
|
|
13
|
+
scales: list[float] = field(default_factory=list)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def resolve_lora_params(ctx: AppContext, loras: Iterable[LoraRef]) -> LoraParams:
|
|
17
|
+
params = LoraParams()
|
|
18
|
+
|
|
19
|
+
for lr in loras:
|
|
20
|
+
params.paths.append(get_file_path(ctx.file_store, lr.file, kind="lora"))
|
|
21
|
+
params.scales.append(lr.scale)
|
|
22
|
+
|
|
23
|
+
return params
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""Merge a train request with settings defaults into the complete TrainParams."""
|
|
2
|
+
|
|
3
|
+
from .._settings import Flux2Settings
|
|
4
|
+
from .._views.train_params import TrainParams
|
|
5
|
+
from .._views.train_request import TrainRequest
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def resolve_train_params(
|
|
9
|
+
settings: Flux2Settings,
|
|
10
|
+
req: TrainRequest,
|
|
11
|
+
*,
|
|
12
|
+
variant: str,
|
|
13
|
+
) -> TrainParams:
|
|
14
|
+
steps = (
|
|
15
|
+
req.steps if req.steps is not None else settings.train_steps.get(variant, 40)
|
|
16
|
+
)
|
|
17
|
+
return TrainParams(
|
|
18
|
+
training_mode=req.training_mode,
|
|
19
|
+
seed=req.seed,
|
|
20
|
+
steps=steps,
|
|
21
|
+
guidance=req.guidance,
|
|
22
|
+
quantize=(
|
|
23
|
+
req.quantize
|
|
24
|
+
if req.quantize is not None
|
|
25
|
+
else settings.train_quantize.get(variant, 8)
|
|
26
|
+
),
|
|
27
|
+
max_resolution=req.max_resolution,
|
|
28
|
+
low_ram=req.low_ram,
|
|
29
|
+
num_epochs=req.num_epochs,
|
|
30
|
+
batch_size=req.batch_size,
|
|
31
|
+
timestep_low=(
|
|
32
|
+
req.timestep_low
|
|
33
|
+
if req.timestep_low is not None
|
|
34
|
+
else settings.train_timestep_low.get(variant, 25)
|
|
35
|
+
),
|
|
36
|
+
timestep_high=req.timestep_high if req.timestep_high is not None else steps,
|
|
37
|
+
learning_rate=req.learning_rate,
|
|
38
|
+
save_frequency=req.save_frequency if req.save_frequency is not None else 10**9,
|
|
39
|
+
lora_rank=req.lora_rank,
|
|
40
|
+
lora_include_ff=req.lora_include_ff,
|
|
41
|
+
lora_layers=req.lora_layers,
|
|
42
|
+
)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""Derive a role-specific ModelSpec (its repo carries a ``#<role>`` marker).
|
|
2
|
+
|
|
3
|
+
The edit role loads a different mflux class than generate, so edit acquires a
|
|
4
|
+
resident model under a spec whose repo is tagged with the role.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from kiapi.core.model import ModelSpec
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def role_spec(spec: ModelSpec, role: str) -> ModelSpec:
|
|
11
|
+
if role == "generate":
|
|
12
|
+
return spec
|
|
13
|
+
return spec.model_copy(update={"repo": f"{spec.repo}#{role}"})
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""Split a flux2 spec repo into ``(model_name, role)``.
|
|
2
|
+
|
|
3
|
+
A role marker is appended to a spec's ``repo`` as ``<repo>#<role>`` so a single
|
|
4
|
+
family registration can yield distinct resident models per role (generate/edit).
|
|
5
|
+
A bare repo means the default ``generate`` role.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def split_repo(repo: str) -> tuple[str, str]:
|
|
10
|
+
base, sep, role = repo.partition("#")
|
|
11
|
+
return base, role if sep else "generate"
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from kiapi.capabilities import ValidationError
|
|
2
|
+
|
|
3
|
+
from .._settings import Flux2Settings
|
|
4
|
+
from .._views.edit_request import EditRequest
|
|
5
|
+
from .._views.generate_request import GenerateRequest
|
|
6
|
+
|
|
7
|
+
_MULTIPLE = 16
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def validate_common(
|
|
11
|
+
req: GenerateRequest | EditRequest, settings: Flux2Settings, *, variant: str
|
|
12
|
+
) -> None:
|
|
13
|
+
width = req.width if req.width is not None else settings.default_width
|
|
14
|
+
height = req.height if req.height is not None else settings.default_height
|
|
15
|
+
|
|
16
|
+
if width <= 0 or height <= 0:
|
|
17
|
+
raise ValidationError("width and height must be positive")
|
|
18
|
+
if width % _MULTIPLE or height % _MULTIPLE:
|
|
19
|
+
raise ValidationError(f"width and height must be multiples of {_MULTIPLE}")
|
|
20
|
+
if width > settings.max_width or height > settings.max_height:
|
|
21
|
+
raise ValidationError(
|
|
22
|
+
f"size {width}x{height} exceeds the cap {settings.max_width}x{settings.max_height}"
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
steps = (
|
|
26
|
+
req.steps if req.steps is not None else settings.default_steps.get(variant, 4)
|
|
27
|
+
)
|
|
28
|
+
if steps < 1 or steps > settings.max_steps:
|
|
29
|
+
raise ValidationError(f"steps must be in 1..{settings.max_steps}")
|
|
30
|
+
if req.quantize is not None and req.quantize not in (3, 4, 5, 6, 8):
|
|
31
|
+
raise ValidationError("quantize must be one of 3, 4, 5, 6, 8")
|
|
32
|
+
if len(req.loras) > settings.max_loras:
|
|
33
|
+
raise ValidationError(f"at most {settings.max_loras} loras may be applied")
|
|
34
|
+
if req.image_strength is not None and not 0 <= req.image_strength <= 1:
|
|
35
|
+
raise ValidationError("image_strength must be in 0..1")
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""A single LoRA adapter reference (file + scale) applied to a flux2 run."""
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, Field
|
|
4
|
+
|
|
5
|
+
from kiapi.core.file import FileRef
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class LoraRef(BaseModel):
|
|
9
|
+
"""One LoRA adapter to apply, by Files-API reference and blend scale.
|
|
10
|
+
|
|
11
|
+
Any lora forces a one-off transient model (slower, not reused). Up to 4 may
|
|
12
|
+
be passed in a request's ``loras`` list.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
file: FileRef = Field(
|
|
16
|
+
description=(
|
|
17
|
+
"The LoRA adapter (`.safetensors`) to apply, as a Files-API file id, "
|
|
18
|
+
"http(s) URL, or data URL."
|
|
19
|
+
),
|
|
20
|
+
)
|
|
21
|
+
scale: float = Field(
|
|
22
|
+
default=1.0,
|
|
23
|
+
description=(
|
|
24
|
+
"Blend strength for this adapter. 1.0 applies it at full weight; lower "
|
|
25
|
+
"values weaken its effect, higher values exaggerate it."
|
|
26
|
+
),
|
|
27
|
+
)
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"""FLUX.2 capability defaults + caps, read from ``KIAPI_FLUX2_`` env vars."""
|
|
2
|
+
|
|
3
|
+
from typing import cast
|
|
4
|
+
|
|
5
|
+
from pydantic import Field
|
|
6
|
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
7
|
+
from pydantic_settings_manager import SettingsManager
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Flux2Settings(BaseSettings):
|
|
11
|
+
"""Settings for FLUX.2 model variants, generation defaults, and LoRA training."""
|
|
12
|
+
|
|
13
|
+
model_config = SettingsConfigDict(
|
|
14
|
+
env_prefix="KIAPI_FLUX2_",
|
|
15
|
+
extra="ignore",
|
|
16
|
+
protected_namespaces=(),
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
klein_9b_model: str = Field(
|
|
20
|
+
default="flux2-klein-9b",
|
|
21
|
+
title="Klein 9B model name",
|
|
22
|
+
description="Name registered in the model registry for the FLUX.2 Klein 9B variant.",
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
klein_base_4b_model: str = Field(
|
|
26
|
+
default="flux2-klein-base-4b",
|
|
27
|
+
title="Klein Base 4B model name",
|
|
28
|
+
description="Name registered in the model registry for the FLUX.2 Klein Base 4B variant.",
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
klein_base_9b_model: str = Field(
|
|
32
|
+
default="flux2-klein-base-9b",
|
|
33
|
+
title="Klein Base 9B model name",
|
|
34
|
+
description="Name registered in the model registry for the FLUX.2 Klein Base 9B variant.",
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
# --------------------------------------------------
|
|
38
|
+
# generate
|
|
39
|
+
# --------------------------------------------------
|
|
40
|
+
|
|
41
|
+
default_steps: dict[str, int] = Field(
|
|
42
|
+
default_factory=lambda: {
|
|
43
|
+
"klein-9b": 4,
|
|
44
|
+
"klein-base-4b": 40,
|
|
45
|
+
"klein-base-9b": 40,
|
|
46
|
+
},
|
|
47
|
+
title="Default steps by variant",
|
|
48
|
+
description=(
|
|
49
|
+
"Diffusion step count used when a generation or edit request omits steps.\n"
|
|
50
|
+
"Keys are variant names such as klein-9b; values are step counts."
|
|
51
|
+
),
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
default_guidance: dict[str, float] = Field(
|
|
55
|
+
default_factory=lambda: {
|
|
56
|
+
"klein-9b": 1.0,
|
|
57
|
+
"klein-base-4b": 1.0,
|
|
58
|
+
"klein-base-9b": 1.0,
|
|
59
|
+
},
|
|
60
|
+
title="Default guidance by variant",
|
|
61
|
+
description=(
|
|
62
|
+
"Guidance strength used when a generation or edit request omits guidance.\n"
|
|
63
|
+
"Keys are variant names; values are guidance values."
|
|
64
|
+
),
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
default_quantize: dict[str, int | None] = Field(
|
|
68
|
+
default_factory=lambda: cast(
|
|
69
|
+
dict[str, int | None],
|
|
70
|
+
{
|
|
71
|
+
"klein-9b": None,
|
|
72
|
+
"klein-base-4b": 8,
|
|
73
|
+
"klein-base-9b": 8,
|
|
74
|
+
},
|
|
75
|
+
),
|
|
76
|
+
title="Default quantization bits by variant",
|
|
77
|
+
description=(
|
|
78
|
+
"Default quantization bit count used when loading a model.\n"
|
|
79
|
+
"Keys are variant names; values are bit counts such as 8, or None "
|
|
80
|
+
"for no quantization."
|
|
81
|
+
),
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
default_width: int = Field(
|
|
85
|
+
default=1024,
|
|
86
|
+
title="Default width",
|
|
87
|
+
description="Output image width in pixels used when a request omits width.",
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
default_height: int = Field(
|
|
91
|
+
default=1024,
|
|
92
|
+
title="Default height",
|
|
93
|
+
description="Output image height in pixels used when a request omits height.",
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
max_width: int = Field(
|
|
97
|
+
default=2048,
|
|
98
|
+
title="Maximum width",
|
|
99
|
+
description="Upper pixel limit for the output image width accepted in a request.",
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
max_height: int = Field(
|
|
103
|
+
default=2048,
|
|
104
|
+
title="Maximum height",
|
|
105
|
+
description="Upper pixel limit for the output image height accepted in a request.",
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
max_steps: int = Field(
|
|
109
|
+
default=100,
|
|
110
|
+
title="Maximum inference steps",
|
|
111
|
+
description="Upper limit for the diffusion step count accepted in a request.",
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
max_loras: int = Field(
|
|
115
|
+
default=4,
|
|
116
|
+
title="Maximum LoRA count",
|
|
117
|
+
description="Maximum number of LoRA adapters that can be applied in one generation or edit request.",
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
# --------------------------------------------------
|
|
121
|
+
# train
|
|
122
|
+
# --------------------------------------------------
|
|
123
|
+
|
|
124
|
+
train_default_model: str = Field(
|
|
125
|
+
default="klein-base-4b",
|
|
126
|
+
title="Default LoRA training model",
|
|
127
|
+
description=(
|
|
128
|
+
"FLUX.2 variant name used when a LoRA training request omits model.\n"
|
|
129
|
+
"Usually this should be a training-capable variant such as "
|
|
130
|
+
"klein-base-4b or klein-base-9b."
|
|
131
|
+
),
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
train_reserve_gb: float = Field(
|
|
135
|
+
default=24.0,
|
|
136
|
+
title="LoRA training reserved memory GB",
|
|
137
|
+
description="Memory in GB reserved for the runtime peak of a FLUX.2 LoRA training job.",
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
train_steps: dict[str, int] = Field(
|
|
141
|
+
default_factory=lambda: {
|
|
142
|
+
"klein-base-4b": 40,
|
|
143
|
+
"klein-base-9b": 40,
|
|
144
|
+
},
|
|
145
|
+
title="Training steps by variant",
|
|
146
|
+
description=(
|
|
147
|
+
"Step count used when a LoRA training request omits steps.\n"
|
|
148
|
+
"Keys are variant names; values are training step counts."
|
|
149
|
+
),
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
train_timestep_low: dict[str, int] = Field(
|
|
153
|
+
default_factory=lambda: {
|
|
154
|
+
"klein-base-4b": 25,
|
|
155
|
+
"klein-base-9b": 25,
|
|
156
|
+
},
|
|
157
|
+
title="Training timestep lower bound by variant",
|
|
158
|
+
description=(
|
|
159
|
+
"Lower bound of the timestep range used during LoRA training.\n"
|
|
160
|
+
"Keys are variant names; values are lower-bound timestep values."
|
|
161
|
+
),
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
train_quantize: dict[str, int | None] = Field(
|
|
165
|
+
default_factory=lambda: cast(
|
|
166
|
+
dict[str, int | None],
|
|
167
|
+
{
|
|
168
|
+
"klein-base-4b": 8,
|
|
169
|
+
"klein-base-9b": 8,
|
|
170
|
+
},
|
|
171
|
+
),
|
|
172
|
+
title="Training quantization bits by variant",
|
|
173
|
+
description=(
|
|
174
|
+
"Quantization bit count applied to the model during LoRA training.\n"
|
|
175
|
+
"Keys are variant names; values are bit counts such as 8, or None "
|
|
176
|
+
"for no quantization."
|
|
177
|
+
),
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
settings_manager = SettingsManager(Flux2Settings)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""The complete contract for one FLUX.2 multi-reference edit run.
|
|
2
|
+
|
|
3
|
+
Built from settings + request by ``resolve_edit_params``; the model needs nothing
|
|
4
|
+
else to produce the image and its metadata. ``image_paths`` are the locally
|
|
5
|
+
resolved input files, kept out of the recorded metadata in favour of
|
|
6
|
+
``image_file_ids``.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from typing import Literal
|
|
10
|
+
|
|
11
|
+
from pydantic import BaseModel
|
|
12
|
+
|
|
13
|
+
from .._schemas.lora_ref import LoraRef
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class EditParams(BaseModel):
|
|
17
|
+
kind: Literal["edit"] = "edit"
|
|
18
|
+
model: str
|
|
19
|
+
|
|
20
|
+
prompt: str
|
|
21
|
+
image_file_ids: list[str]
|
|
22
|
+
image_paths: list[str]
|
|
23
|
+
image_strength: float | None
|
|
24
|
+
|
|
25
|
+
seed: int
|
|
26
|
+
width: int
|
|
27
|
+
height: int
|
|
28
|
+
steps: int
|
|
29
|
+
guidance: float
|
|
30
|
+
quantize: int | None
|
|
31
|
+
scheduler: str
|
|
32
|
+
|
|
33
|
+
format: Literal["png", "jpeg", "webp"]
|
|
34
|
+
quality: int
|
|
35
|
+
|
|
36
|
+
loras: list[LoraRef]
|