horde-engine 3.2.9__tar.gz → 3.3.0__tar.gz

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.
Files changed (239) hide show
  1. {horde_engine-3.2.9 → horde_engine-3.3.0}/PKG-INFO +1 -1
  2. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/_version.py +2 -2
  3. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/api.py +37 -1
  4. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/comfy_horde.py +72 -3
  5. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/feature_impact.py +19 -0
  6. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/utils/torch_memory.py +48 -1
  7. horde_engine-3.3.0/hordelib/vram_planning.py +92 -0
  8. {horde_engine-3.2.9 → horde_engine-3.3.0}/.gitignore +0 -0
  9. {horde_engine-3.2.9 → horde_engine-3.3.0}/LICENSE +0 -0
  10. {horde_engine-3.2.9 → horde_engine-3.3.0}/README.md +0 -0
  11. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/__init__.py +0 -0
  12. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/__pyinstaller.py +0 -0
  13. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/benchmark.py +0 -0
  14. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/beta_models.py +0 -0
  15. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/config_path.py +0 -0
  16. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/consts.py +0 -0
  17. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/exceptions.py +0 -0
  18. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/execution/__init__.py +0 -0
  19. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/execution/comfy_patches.py +0 -0
  20. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/execution/graph_utils.py +0 -0
  21. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/execution/in_process.py +0 -0
  22. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/execution/interface.py +0 -0
  23. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/execution/phase_timing.py +0 -0
  24. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/execution/progress_hook.py +0 -0
  25. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/execution/sampling_lease.py +0 -0
  26. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/feature_requirements.py +0 -0
  27. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/horde.py +0 -0
  28. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/initialisation.py +0 -0
  29. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/installation/__init__.py +0 -0
  30. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/installation/__main__.py +0 -0
  31. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/installation/installer.py +0 -0
  32. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/installation/manifest.json +0 -0
  33. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/installation/manifest.py +0 -0
  34. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/integrations/__init__.py +0 -0
  35. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/integrations/logfire_comfy_internals.py +0 -0
  36. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/integrations/logfire_setup.py +0 -0
  37. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/metrics.py +0 -0
  38. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/model_database/db_dep.json +0 -0
  39. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/model_database/db_embeds.json +0 -0
  40. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/model_database/diffusers.json +0 -0
  41. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/model_database/med_config.json +0 -0
  42. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/model_manager/__init__.py +0 -0
  43. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/model_manager/base.py +0 -0
  44. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/model_manager/civitai_adhoc.py +0 -0
  45. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/model_manager/civitai_provider.py +0 -0
  46. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/model_manager/civitai_records.py +0 -0
  47. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/model_manager/codeformer.py +0 -0
  48. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/model_manager/compvis.py +0 -0
  49. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/model_manager/controlnet.py +0 -0
  50. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/model_manager/diffusers.py +0 -0
  51. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/model_manager/esrgan.py +0 -0
  52. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/model_manager/gfpgan.py +0 -0
  53. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/model_manager/hyper.py +0 -0
  54. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/model_manager/lora.py +0 -0
  55. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/model_manager/miscellaneous.py +0 -0
  56. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/model_manager/safety_checker.py +0 -0
  57. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/model_manager/ti.py +0 -0
  58. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/__init__.py +0 -0
  59. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/comfyui_layerdiffuse/LICENSE +0 -0
  60. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/comfyui_layerdiffuse/README.md +0 -0
  61. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/comfyui_layerdiffuse/__init__.py +0 -0
  62. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/comfyui_layerdiffuse/examples/layer_diffusion_cond_example.json +0 -0
  63. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/comfyui_layerdiffuse/examples/layer_diffusion_cond_fg_all.json +0 -0
  64. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/comfyui_layerdiffuse/examples/layer_diffusion_cond_joint_bg.json +0 -0
  65. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/comfyui_layerdiffuse/examples/layer_diffusion_cond_joint_fg.json +0 -0
  66. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/comfyui_layerdiffuse/examples/layer_diffusion_diff_bg.json +0 -0
  67. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/comfyui_layerdiffuse/examples/layer_diffusion_diff_bg_stop_at.json +0 -0
  68. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/comfyui_layerdiffuse/examples/layer_diffusion_diff_fg.json +0 -0
  69. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/comfyui_layerdiffuse/examples/layer_diffusion_fg_example.json +0 -0
  70. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/comfyui_layerdiffuse/examples/layer_diffusion_fg_example_rgba.json +0 -0
  71. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/comfyui_layerdiffuse/examples/layer_diffusion_joint.json +0 -0
  72. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/comfyui_layerdiffuse/layered_diffusion.py +0 -0
  73. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/comfyui_layerdiffuse/lib_layerdiffusion/__init__.py +0 -0
  74. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/comfyui_layerdiffuse/lib_layerdiffusion/attention_sharing.py +0 -0
  75. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/comfyui_layerdiffuse/lib_layerdiffusion/enums.py +0 -0
  76. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/comfyui_layerdiffuse/lib_layerdiffusion/models.py +0 -0
  77. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/comfyui_layerdiffuse/lib_layerdiffusion/utils.py +0 -0
  78. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/comfyui_layerdiffuse/pyproject.toml +0 -0
  79. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/comfyui_layerdiffuse/requirements.txt +0 -0
  80. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/LICENSE +0 -0
  81. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/README.md +0 -0
  82. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/__init__.py +0 -0
  83. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/VERSION +0 -0
  84. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/__init__.py +0 -0
  85. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/archs/__init__.py +0 -0
  86. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/archs/arcface_arch.py +0 -0
  87. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/archs/arch_util.py +0 -0
  88. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/archs/codeformer_arch.py +0 -0
  89. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/archs/rrdbnet_arch.py +0 -0
  90. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/archs/vgg_arch.py +0 -0
  91. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/archs/vqgan_arch.py +0 -0
  92. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/data/__init__.py +0 -0
  93. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/data/data_sampler.py +0 -0
  94. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/data/data_util.py +0 -0
  95. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/data/prefetch_dataloader.py +0 -0
  96. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/data/transforms.py +0 -0
  97. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/losses/__init__.py +0 -0
  98. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/losses/loss_util.py +0 -0
  99. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/losses/losses.py +0 -0
  100. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/metrics/__init__.py +0 -0
  101. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/metrics/metric_util.py +0 -0
  102. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/metrics/psnr_ssim.py +0 -0
  103. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/models/__init__.py +0 -0
  104. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/ops/__init__.py +0 -0
  105. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/ops/dcn/__init__.py +0 -0
  106. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/ops/dcn/deform_conv.py +0 -0
  107. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/ops/dcn/src/deform_conv_cuda.cpp +0 -0
  108. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/ops/dcn/src/deform_conv_cuda_kernel.cu +0 -0
  109. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/ops/dcn/src/deform_conv_ext.cpp +0 -0
  110. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/ops/fused_act/__init__.py +0 -0
  111. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/ops/fused_act/fused_act.py +0 -0
  112. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/ops/fused_act/src/fused_bias_act.cpp +0 -0
  113. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/ops/fused_act/src/fused_bias_act_kernel.cu +0 -0
  114. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/ops/upfirdn2d/__init__.py +0 -0
  115. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/ops/upfirdn2d/src/upfirdn2d.cpp +0 -0
  116. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/ops/upfirdn2d/src/upfirdn2d_kernel.cu +0 -0
  117. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/ops/upfirdn2d/upfirdn2d.py +0 -0
  118. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/setup.py +0 -0
  119. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/train.py +0 -0
  120. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/utils/__init__.py +0 -0
  121. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/utils/dist_util.py +0 -0
  122. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/utils/download_util.py +0 -0
  123. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/utils/file_client.py +0 -0
  124. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/utils/img_util.py +0 -0
  125. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/utils/lmdb_util.py +0 -0
  126. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/utils/logger.py +0 -0
  127. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/utils/matlab_functions.py +0 -0
  128. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/utils/misc.py +0 -0
  129. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/utils/options.py +0 -0
  130. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/utils/realesrgan_utils.py +0 -0
  131. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/utils/registry.py +0 -0
  132. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/basicsr/version.py +0 -0
  133. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/facelib/__init__.py +0 -0
  134. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/facelib/detection/__init__.py +0 -0
  135. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/facelib/detection/align_trans.py +0 -0
  136. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/facelib/detection/matlab_cp2tform.py +0 -0
  137. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/facelib/detection/retinaface/retinaface.py +0 -0
  138. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/facelib/detection/retinaface/retinaface_net.py +0 -0
  139. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/facelib/detection/retinaface/retinaface_utils.py +0 -0
  140. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/facelib/detection/yolov5face/__init__.py +0 -0
  141. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/facelib/detection/yolov5face/face_detector.py +0 -0
  142. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/facelib/detection/yolov5face/models/__init__.py +0 -0
  143. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/facelib/detection/yolov5face/models/common.py +0 -0
  144. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/facelib/detection/yolov5face/models/experimental.py +0 -0
  145. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/facelib/detection/yolov5face/models/yolo.py +0 -0
  146. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/facelib/detection/yolov5face/models/yolov5l.yaml +0 -0
  147. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/facelib/detection/yolov5face/models/yolov5n.yaml +0 -0
  148. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/facelib/detection/yolov5face/utils/__init__.py +0 -0
  149. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/facelib/detection/yolov5face/utils/autoanchor.py +0 -0
  150. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/facelib/detection/yolov5face/utils/datasets.py +0 -0
  151. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/facelib/detection/yolov5face/utils/extract_ckpt.py +0 -0
  152. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/facelib/detection/yolov5face/utils/general.py +0 -0
  153. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/facelib/detection/yolov5face/utils/torch_utils.py +0 -0
  154. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/facelib/parsing/__init__.py +0 -0
  155. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/facelib/parsing/bisenet.py +0 -0
  156. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/facelib/parsing/parsenet.py +0 -0
  157. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/facelib/parsing/resnet.py +0 -0
  158. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/facelib/utils/__init__.py +0 -0
  159. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/facelib/utils/face_restoration_helper.py +0 -0
  160. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/facelib/utils/face_utils.py +0 -0
  161. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/facelib/utils/misc.py +0 -0
  162. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/r_chainner/README.md +0 -0
  163. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/r_chainner/__init__.py +0 -0
  164. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/r_chainner/gfpganv1_clean_arch.py +0 -0
  165. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/r_chainner/model_loading.py +0 -0
  166. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/r_chainner/stylegan2_clean_arch.py +0 -0
  167. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/facerestore_cf/r_chainner/types.py +0 -0
  168. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/node_controlnet_model_loader.py +0 -0
  169. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/node_image_loader.py +0 -0
  170. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/node_image_output.py +0 -0
  171. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/node_lora_loader.py +0 -0
  172. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/node_model_loader.py +0 -0
  173. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/nodes/node_upscale_model_loader.py +0 -0
  174. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipeline/__init__.py +0 -0
  175. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipeline/constants.py +0 -0
  176. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipeline/context.py +0 -0
  177. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipeline/families/__init__.py +0 -0
  178. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipeline/families/image.py +0 -0
  179. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipeline/families/post_processing.py +0 -0
  180. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipeline/graph.py +0 -0
  181. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipeline/horde_compat.py +0 -0
  182. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipeline/patches.py +0 -0
  183. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipeline/payload.py +0 -0
  184. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipeline/payload_pp.py +0 -0
  185. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipeline/registry.py +0 -0
  186. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipeline/resolution.py +0 -0
  187. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipeline/template.py +0 -0
  188. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipeline_designs/pipeline_controlnet.json +0 -0
  189. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipeline_designs/pipeline_controlnet_annotator.json +0 -0
  190. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipeline_designs/pipeline_controlnet_hires_fix.json +0 -0
  191. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipeline_designs/pipeline_flux.json +0 -0
  192. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipeline_designs/pipeline_image_facefix.json +0 -0
  193. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipeline_designs/pipeline_image_upscale.json +0 -0
  194. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipeline_designs/pipeline_qr_code.json +0 -0
  195. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipeline_designs/pipeline_qwen.json +0 -0
  196. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipeline_designs/pipeline_stable_cascade.json +0 -0
  197. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipeline_designs/pipeline_stable_cascade_2pass.json +0 -0
  198. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipeline_designs/pipeline_stable_cascade_remix.json +0 -0
  199. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipeline_designs/pipeline_stable_diffusion.json +0 -0
  200. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipeline_designs/pipeline_stable_diffusion_hires_fix.json +0 -0
  201. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipeline_designs/pipeline_stable_diffusion_img2img_mask.json +0 -0
  202. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipeline_designs/pipeline_stable_diffusion_paint.json +0 -0
  203. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipelines/pipeline_controlnet.json +0 -0
  204. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipelines/pipeline_controlnet_annotator.json +0 -0
  205. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipelines/pipeline_controlnet_hires_fix.json +0 -0
  206. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipelines/pipeline_flux.json +0 -0
  207. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipelines/pipeline_image_facefix.json +0 -0
  208. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipelines/pipeline_image_upscale.json +0 -0
  209. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipelines/pipeline_qr_code.json +0 -0
  210. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipelines/pipeline_qwen.json +0 -0
  211. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipelines/pipeline_stable_cascade.json +0 -0
  212. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipelines/pipeline_stable_cascade_2pass.json +0 -0
  213. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipelines/pipeline_stable_cascade_remix.json +0 -0
  214. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipelines/pipeline_stable_diffusion.json +0 -0
  215. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipelines/pipeline_stable_diffusion_hires_fix.json +0 -0
  216. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipelines/pipeline_stable_diffusion_img2img_mask.json +0 -0
  217. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pipelines/pipeline_stable_diffusion_paint.json +0 -0
  218. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/preload.py +0 -0
  219. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/py.typed +0 -0
  220. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pyinstaller_hooks/__init__.py +0 -0
  221. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/pyinstaller_hooks/hook-hordelib.horde.py +0 -0
  222. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/safety.py +0 -0
  223. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/safety_checker.py +0 -0
  224. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/settings.py +0 -0
  225. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/shared_model_manager.py +0 -0
  226. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/train.py +0 -0
  227. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/utils/__init__.py +0 -0
  228. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/utils/distance.py +0 -0
  229. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/utils/dynamicprompt.py +0 -0
  230. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/utils/gpuinfo.py +0 -0
  231. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/utils/image_utils.py +0 -0
  232. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/utils/ioredirect.py +0 -0
  233. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/utils/logger.py +0 -0
  234. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/utils/nvml.py +0 -0
  235. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/utils/optional_deps.py +0 -0
  236. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/utils/sanitizer.py +0 -0
  237. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/utils/switch.py +0 -0
  238. {horde_engine-3.2.9 → horde_engine-3.3.0}/hordelib/utils/torch_build.py +0 -0
  239. {horde_engine-3.2.9 → horde_engine-3.3.0}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: horde-engine
3
- Version: 3.2.9
3
+ Version: 3.3.0
4
4
  Summary: A wrapper around ComfyUI to allow use by AI Horde.
5
5
  Project-URL: Homepage, https://github.com/Haidra-Org/hordelib
6
6
  Project-URL: Bug Tracker, https://github.com/Haidra-Org/hordelib/issues
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '3.2.9'
22
- __version_tuple__ = version_tuple = (3, 2, 9)
21
+ __version__ = version = '3.3.0'
22
+ __version_tuple__ = version_tuple = (3, 3, 0)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -7,6 +7,8 @@ nothing here triggers a ComfyUI import (``hordelib.initialise()`` does that expl
7
7
  The contract is enforced by ``tests/meta/test_public_api_contract.py``.
8
8
  """
9
9
 
10
+ from typing import TYPE_CHECKING
11
+
10
12
  from hordelib import initialise, is_initialised
11
13
  from hordelib.execution.interface import (
12
14
  ExecutionBackend,
@@ -67,7 +69,6 @@ from hordelib.pipeline.payload_pp import (
67
69
  classify_post_processor,
68
70
  )
69
71
  from hordelib.preload import controlnet_annotators_present
70
- from hordelib.shared_model_manager import SharedModelManager
71
72
  from hordelib.utils.ioredirect import ComfyUIProgress, ComfyUIProgressUnit
72
73
  from hordelib.utils.logger import HordeLog
73
74
  from hordelib.utils.torch_memory import (
@@ -77,10 +78,22 @@ from hordelib.utils.torch_memory import (
77
78
  enumerate_accelerators,
78
79
  get_accelerator_utilization_percent,
79
80
  get_free_ram_mb,
81
+ get_loaded_weights_offloaded_mb,
82
+ get_torch_device_free_vram_mb,
80
83
  get_torch_free_vram_mb,
81
84
  get_torch_total_vram_mb,
82
85
  log_free_ram,
83
86
  )
87
+ from hordelib.vram_planning import (
88
+ compute_extra_reserved_mb,
89
+ compute_inference_reserve_mb,
90
+ compute_weight_budget_mb,
91
+ )
92
+
93
+ if TYPE_CHECKING:
94
+ # Re-exported lazily (see ``__getattr__`` below) so the type checker still sees the name without the
95
+ # eager import that would drag torch into every consumer of this facade.
96
+ from hordelib.shared_model_manager import SharedModelManager
84
97
 
85
98
  __all__ = [
86
99
  "CONTROLNET_ANNOTATOR_DOWNLOAD_BYTES",
@@ -121,6 +134,9 @@ __all__ = [
121
134
  "available_features",
122
135
  "classify_post_processor",
123
136
  "clear_accelerator_cache",
137
+ "compute_extra_reserved_mb",
138
+ "compute_inference_reserve_mb",
139
+ "compute_weight_budget_mb",
124
140
  "controlnet_annotator_download_bytes",
125
141
  "controlnet_annotators_present",
126
142
  "enumerate_accelerators",
@@ -133,6 +149,8 @@ __all__ = [
133
149
  "missing_packages",
134
150
  "get_accelerator_utilization_percent",
135
151
  "get_free_ram_mb",
152
+ "get_loaded_weights_offloaded_mb",
153
+ "get_torch_device_free_vram_mb",
136
154
  "get_metrics_collector",
137
155
  "get_torch_free_vram_mb",
138
156
  "get_torch_total_vram_mb",
@@ -142,3 +160,21 @@ __all__ = [
142
160
  "log_free_ram",
143
161
  "set_gpu_sampling_lease",
144
162
  ]
163
+
164
+
165
+ def __getattr__(name: str) -> object:
166
+ """Lazily resolve the one torch-heavy re-export so the facade's import cost stays honest.
167
+
168
+ Every other name above comes from a torch-free submodule, so ``import hordelib.api`` is cheap
169
+ (~75MB) and pulls no torch. ``SharedModelManager`` is the exception: it transitively imports the
170
+ concrete model managers, which import torch (~500MB RSS). Re-exporting it eagerly would tax every
171
+ consumer of this facade with a full torch load, including the worker's torch-free orchestrator and
172
+ benchmark planner that only want the pure-Python helpers. PEP 562 module ``__getattr__`` defers that
173
+ import until ``SharedModelManager`` is actually accessed, so a consumer pays for torch only when it
174
+ asks for something that genuinely needs it.
175
+ """
176
+ if name == "SharedModelManager":
177
+ from hordelib.shared_model_manager import SharedModelManager
178
+
179
+ return SharedModelManager
180
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
@@ -511,12 +511,81 @@ def get_torch_free_vram_mb():
511
511
  return round(_comfy_get_free_memory() / (1024 * 1024))
512
512
 
513
513
 
514
+ def get_torch_device_free_vram_mb():
515
+ """Device-wide free VRAM (mem_get_info), excluding this process's reclaimable torch cache.
516
+
517
+ See :func:`hordelib.utils.torch_memory.get_torch_device_free_vram_mb`. This is the honest figure for
518
+ over-commit/streaming decisions; ``get_torch_free_vram_mb`` (comfy's view) adds back a single
519
+ process's cache and so over-states cross-process headroom.
520
+ """
521
+ from hordelib.utils.torch_memory import get_torch_device_free_vram_mb as _device_free
522
+
523
+ return _device_free()
524
+
525
+
526
+ _LAST_LOW_VRAM_WARN_TIME: float = 0.0
527
+ """Monotonic-ish wall time of the last low-free-VRAM warning, so a job that runs its whole length below the
528
+ inference reserve warns periodically rather than on every (very frequent) log_free_ram call."""
529
+ _LOW_VRAM_WARN_INTERVAL_SECONDS: float = 15.0
530
+
531
+
514
532
  def log_free_ram():
515
- logger.debug(
516
- f"Free VRAM: {get_torch_free_vram_mb():0.0f} MB, "
517
- f"Free RAM: {psutil.virtual_memory().available / (1024 * 1024):0.0f} MB",
533
+ global _LAST_LOW_VRAM_WARN_TIME
534
+
535
+ # Report the *device-wide* free VRAM (mem_get_info), not comfy's get_free_memory: the latter adds back
536
+ # this process's reserved-but-inactive torch allocator cache, over-stating free by several GB and
537
+ # hiding VRAM held by other (including leaked) processes. The driver's system-memory fallback triggers
538
+ # on the device-wide figure, so that is the honest number for a streaming/over-commit warning.
539
+ free_vram_mb = get_torch_device_free_vram_mb()
540
+ comfy_free_vram_mb = get_torch_free_vram_mb()
541
+ reclaimable_cache_mb = max(0.0, comfy_free_vram_mb - free_vram_mb)
542
+ free_ram_mb = psutil.virtual_memory().available / (1024 * 1024)
543
+
544
+ offloaded_mb = 0
545
+ try:
546
+ from hordelib.utils.torch_memory import get_loaded_weights_offloaded_mb
547
+
548
+ offloaded_mb = get_loaded_weights_offloaded_mb()
549
+ except Exception:
550
+ offloaded_mb = 0
551
+ offloaded_note = f", Weights offloaded to RAM: {offloaded_mb:0.0f} MB" if offloaded_mb > 0 else ""
552
+ # Surface the gap between the device-wide free and comfy's view so a live run shows how much of the
553
+ # apparent headroom is merely this process's reclaimable cache (returned by empty_cache), not room a
554
+ # sibling model load could actually use.
555
+ cache_note = (
556
+ f" (+{reclaimable_cache_mb:0.0f} MB reclaimable torch cache; comfy sees {comfy_free_vram_mb:0.0f})"
557
+ if reclaimable_cache_mb >= 256
558
+ else ""
518
559
  )
519
560
 
561
+ logger.debug(f"Free VRAM: {free_vram_mb:0.0f} MB{cache_note}, Free RAM: {free_ram_mb:0.0f} MB{offloaded_note}")
562
+
563
+ # A driver-level system-memory fallback (e.g. the Windows WDDM shared-memory pool, on by default) spills
564
+ # device allocations to host RAM once free VRAM nears zero, collapsing the sampling rate the same way
565
+ # ComfyUI's own weight offloading does but *without* appearing in its offload accounting. ComfyUI can
566
+ # report a model as fully resident while the driver pages its per-step activations. So warn purely on
567
+ # measured free VRAM falling below the inference working-set reserve: below that floor a sampling step has
568
+ # no room for its activations and something (ComfyUI or the driver) must stream over the bus. Throttled so
569
+ # a job that stays under the floor for its whole run periodically reports rather than flooding the log.
570
+ try:
571
+ from hordelib.vram_planning import compute_inference_reserve_mb
572
+
573
+ reserve_mb = compute_inference_reserve_mb(get_torch_total_vram_mb())
574
+ except Exception:
575
+ return
576
+ if free_vram_mb < reserve_mb:
577
+ now = time.time()
578
+ if now - _LAST_LOW_VRAM_WARN_TIME >= _LOW_VRAM_WARN_INTERVAL_SECONDS:
579
+ _LAST_LOW_VRAM_WARN_TIME = now
580
+ if offloaded_mb > 0:
581
+ cause = f"ComfyUI reports {offloaded_mb:0.0f} MB of weights offloaded"
582
+ else:
583
+ cause = "ComfyUI reports no offload, so the GPU driver's system-memory fallback is the likely cause"
584
+ logger.warning(
585
+ f"Free VRAM {free_vram_mb:0.0f} MB is below the {reserve_mb:0.0f} MB inference reserve: "
586
+ f"sampling activations will stream from host RAM and run several times slower ({cause}).",
587
+ )
588
+
520
589
 
521
590
  def interrupt_comfyui_processing():
522
591
  logger.warning("Interrupting comfyui processing")
@@ -73,6 +73,18 @@ class BaselineBurden(BaseModel):
73
73
  max_recommended_batch: int
74
74
  typical_disk_gb: float
75
75
  """Typical checkpoint size on disk, used when no model record is available."""
76
+ vram_weights_mb: int = 0
77
+ """Resident weight footprint (MB) at the baseline's typical worker dtype, distinct from activations.
78
+
79
+ This is the figure ComfyUI compares against its weight budget when deciding whether to keep weights
80
+ resident or stream them from host RAM, so it (not the activation-inflated ``vram_base_mb``) is what a
81
+ consumer should use to forecast streaming and whole-card residency. Zero means unspecified, in which
82
+ case :meth:`resident_weight_estimate_mb` falls back to ``vram_base_mb``. The seeded figures reflect the
83
+ dtypes the worker typically runs on consumer cards (for example, a Flux fp8 checkpoint)."""
84
+
85
+ def resident_weight_estimate_mb(self) -> int:
86
+ """Return the resident weight footprint (MB), falling back to the conflated base when unseeded."""
87
+ return self.vram_weights_mb or self.vram_base_mb
76
88
 
77
89
 
78
90
  class BurdenEstimate(BaseModel):
@@ -153,6 +165,7 @@ _BASELINE_SEEDS: list[BaselineBurden] = [
153
165
  min_recommended_vram_mb=8000,
154
166
  max_recommended_batch=4,
155
167
  typical_disk_gb=6.9,
168
+ vram_weights_mb=4900,
156
169
  ),
157
170
  BaselineBurden(
158
171
  baseline="stable_cascade",
@@ -163,6 +176,7 @@ _BASELINE_SEEDS: list[BaselineBurden] = [
163
176
  min_recommended_vram_mb=10000,
164
177
  max_recommended_batch=2,
165
178
  typical_disk_gb=9.0,
179
+ vram_weights_mb=8000,
166
180
  ),
167
181
  BaselineBurden(
168
182
  baseline="flux_1",
@@ -173,6 +187,7 @@ _BASELINE_SEEDS: list[BaselineBurden] = [
173
187
  min_recommended_vram_mb=14000,
174
188
  max_recommended_batch=1,
175
189
  typical_disk_gb=17.0,
190
+ vram_weights_mb=11500,
176
191
  ),
177
192
  BaselineBurden(
178
193
  baseline="flux_schnell",
@@ -183,6 +198,7 @@ _BASELINE_SEEDS: list[BaselineBurden] = [
183
198
  min_recommended_vram_mb=14000,
184
199
  max_recommended_batch=1,
185
200
  typical_disk_gb=17.0,
201
+ vram_weights_mb=11500,
186
202
  ),
187
203
  BaselineBurden(
188
204
  baseline="flux_dev",
@@ -193,6 +209,7 @@ _BASELINE_SEEDS: list[BaselineBurden] = [
193
209
  min_recommended_vram_mb=14000,
194
210
  max_recommended_batch=1,
195
211
  typical_disk_gb=17.0,
212
+ vram_weights_mb=11500,
196
213
  ),
197
214
  BaselineBurden(
198
215
  baseline="qwen_image",
@@ -203,6 +220,7 @@ _BASELINE_SEEDS: list[BaselineBurden] = [
203
220
  min_recommended_vram_mb=16000,
204
221
  max_recommended_batch=1,
205
222
  typical_disk_gb=20.0,
223
+ vram_weights_mb=12000,
206
224
  ),
207
225
  BaselineBurden(
208
226
  baseline="z_image_turbo",
@@ -225,6 +243,7 @@ _FALLBACK_BASELINE_BURDEN = BaselineBurden(
225
243
  min_recommended_vram_mb=10000,
226
244
  max_recommended_batch=1,
227
245
  typical_disk_gb=8.0,
246
+ vram_weights_mb=7000,
228
247
  )
229
248
  """Used for baselines with no registry entry (including ``infer``), erring on the heavy side."""
230
249
 
@@ -132,13 +132,32 @@ def get_torch_free_vram_mb() -> int:
132
132
  return round(_torch_fallback_vram_bytes(free=True) / _MB)
133
133
 
134
134
 
135
+ def get_torch_device_free_vram_mb() -> int:
136
+ """Physically free VRAM on the device, in MB, from the driver's device-wide accounting.
137
+
138
+ Unlike :func:`get_torch_free_vram_mb` (which, when ComfyUI is loaded, returns comfy's
139
+ ``get_free_memory`` == device-wide free PLUS this process's reserved-but-inactive torch allocator
140
+ cache), this is the raw device-wide free from ``mem_get_info``. The distinction is load-bearing for
141
+ cross-process residency budgeting and for predicting the driver's system-memory fallback: the comfy
142
+ number adds back a single process's reclaimable cache, so it over-states what a *new* allocation can
143
+ use and hides VRAM held by *other* processes (including leaked/orphaned ones). The driver spills to
144
+ host RAM on device-wide free nearing zero, not on the inflated number, so the worker must budget
145
+ against this. Falls back to system RAM on CPU/MPS, matching the other helpers here.
146
+ """
147
+ return round(_torch_fallback_vram_bytes(free=True) / _MB)
148
+
149
+
135
150
  def get_free_ram_mb() -> int:
136
151
  """Available system RAM, in MB."""
137
152
  return round(psutil.virtual_memory().available / _MB)
138
153
 
139
154
 
140
155
  def log_free_ram() -> None:
141
- logger.debug(f"Free VRAM: {get_torch_free_vram_mb():0.0f} MB, Free RAM: {get_free_ram_mb():0.0f} MB")
156
+ offloaded_mb = get_loaded_weights_offloaded_mb()
157
+ offloaded_note = f", Weights offloaded to RAM: {offloaded_mb:0.0f} MB" if offloaded_mb > 0 else ""
158
+ logger.debug(
159
+ f"Free VRAM: {get_torch_free_vram_mb():0.0f} MB, Free RAM: {get_free_ram_mb():0.0f} MB{offloaded_note}",
160
+ )
142
161
 
143
162
 
144
163
  def get_accelerator_utilization_percent(index: int = 0) -> int | None:
@@ -266,6 +285,34 @@ def enumerate_accelerators() -> list[AcceleratorInfo]:
266
285
  return _enumerate_via_torch()
267
286
 
268
287
 
288
+ def get_loaded_weights_offloaded_mb() -> int:
289
+ """Return how much of the currently-loaded models' weights sit off the compute device, in MB.
290
+
291
+ ComfyUI keeps a model fully resident when it fits the weight budget; otherwise it offloads the
292
+ remainder to host RAM and streams it to VRAM during sampling (the slow path that drops device-free
293
+ to near zero and runs several times slower). A non-zero result here is the positive runtime signal
294
+ that weight streaming is happening for the loaded model(s), which the worker uses to confirm a
295
+ streaming forecast and to grant the over-budget step grace instead of killing a slow-but-progressing
296
+ job. Returns 0 when ComfyUI is not loaded in this process or nothing is resident.
297
+ """
298
+ mm = _comfy_model_management()
299
+ if mm is None:
300
+ return 0
301
+ loaded_models = getattr(mm, "current_loaded_models", None)
302
+ if not loaded_models:
303
+ return 0
304
+ offloaded_bytes = 0
305
+ for loaded_model in loaded_models:
306
+ read_offloaded = getattr(loaded_model, "model_offloaded_memory", None)
307
+ if read_offloaded is None:
308
+ continue
309
+ try:
310
+ offloaded_bytes += max(0, int(read_offloaded()))
311
+ except Exception as e:
312
+ logger.debug(f"offloaded-memory read failed for a loaded model: {e}")
313
+ return round(offloaded_bytes / _MB)
314
+
315
+
269
316
  def clear_accelerator_cache() -> None:
270
317
  """Release cached device memory on whatever backend is active (a no-op on CPU).
271
318
 
@@ -0,0 +1,92 @@
1
+ """Pure-Python mirrors of ComfyUI's VRAM accounting, usable before (or without) torch/ComfyUI.
2
+
3
+ The worker's orchestrator decides whether a model will fit a device *before* dispatching it to a
4
+ torch child, and it must do so without importing torch (a ~500MB RSS cost it cannot pay; see the
5
+ torch-free-orchestrator invariant in horde-worker-reGen). ComfyUI's decision to keep a model's
6
+ weights resident or stream them from host RAM hinges on one quantity computed in
7
+ ``comfy/model_management.py``: ``minimum_inference_memory()``, the free VRAM it keeps for activations.
8
+ A model whose weights leave less than that free at load time is offloaded and streamed during
9
+ sampling, which collapses the step rate on a memory-constrained device. This module reproduces that
10
+ formula exactly from the device's total VRAM and platform so the worker can predict streaming and gate
11
+ accordingly.
12
+
13
+ Keep these constants in lockstep with the vendored ``comfy/model_management.py``. For runtime-exact
14
+ agreement (across ComfyUI version skew) prefer the live value a torch child reports; this module is
15
+ the torch-free estimate the orchestrator uses for admission and the no-boot benchmark planner.
16
+
17
+ Comfy-free and torch-free: safe to import in the orchestrator and the benchmark planner.
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ import sys
23
+
24
+ # Mirror of ``comfy/model_management.py`` module-level constants. ComfyUI reserves a base amount of
25
+ # VRAM for other applications, raised on Windows (shared-VRAM driver behaviour) and again on cards
26
+ # above 15GB. An explicit ``--reserve-vram`` overrides all of it.
27
+ _BASE_EXTRA_RESERVED_MB = 400
28
+ _WINDOWS_EXTRA_RESERVED_MB = 600
29
+ _WINDOWS_LARGE_CARD_BONUS_MB = 100
30
+ _LARGE_CARD_THRESHOLD_MB = 15 * 1024
31
+ # The fixed activation working set ComfyUI keeps free on top of the reserve (0.8 GB).
32
+ _INFERENCE_WORKING_SET_MB = 0.8 * 1024
33
+ # ComfyUI scales total VRAM by this before subtracting the reserve to get the static weight budget.
34
+ _WEIGHT_BUDGET_FRACTION = 0.88
35
+
36
+
37
+ def _resolve_is_windows(is_windows: bool | None) -> bool:
38
+ """Return whether to apply ComfyUI's Windows reserve rules (autodetect when not forced)."""
39
+ return sys.platform.startswith("win") if is_windows is None else is_windows
40
+
41
+
42
+ def compute_extra_reserved_mb(
43
+ total_vram_mb: int,
44
+ *,
45
+ is_windows: bool | None = None,
46
+ reserve_vram_gb: float | None = None,
47
+ ) -> int:
48
+ """Return ComfyUI's ``EXTRA_RESERVED_VRAM`` (MB) for a device of ``total_vram_mb``.
49
+
50
+ Mirrors ``comfy/model_management.py``: a base reserve, higher on Windows, with a bonus on cards
51
+ above 15GB. An explicit ``--reserve-vram`` (``reserve_vram_gb``) overrides all of it.
52
+ """
53
+ if reserve_vram_gb is not None:
54
+ return round(reserve_vram_gb * 1024)
55
+ if _resolve_is_windows(is_windows):
56
+ reserved = _WINDOWS_EXTRA_RESERVED_MB
57
+ if total_vram_mb > _LARGE_CARD_THRESHOLD_MB:
58
+ reserved += _WINDOWS_LARGE_CARD_BONUS_MB
59
+ return reserved
60
+ return _BASE_EXTRA_RESERVED_MB
61
+
62
+
63
+ def compute_inference_reserve_mb(
64
+ total_vram_mb: int,
65
+ *,
66
+ is_windows: bool | None = None,
67
+ reserve_vram_gb: float | None = None,
68
+ ) -> int:
69
+ """Return ComfyUI's ``minimum_inference_memory()`` (MB): the free VRAM it keeps for activations.
70
+
71
+ A model whose weights leave less than this free at load time is partially offloaded to host RAM
72
+ and streamed during sampling (the slow path). Equal to the 0.8GB working set plus the extra
73
+ reserve, so it is the headroom the worker must preserve to avoid weight streaming.
74
+ """
75
+ extra = compute_extra_reserved_mb(total_vram_mb, is_windows=is_windows, reserve_vram_gb=reserve_vram_gb)
76
+ return round(_INFERENCE_WORKING_SET_MB + extra)
77
+
78
+
79
+ def compute_weight_budget_mb(
80
+ total_vram_mb: int,
81
+ *,
82
+ is_windows: bool | None = None,
83
+ reserve_vram_gb: float | None = None,
84
+ ) -> int:
85
+ """Return ComfyUI's static ``maximum_vram_for_weights()`` (MB): the most weights can occupy.
86
+
87
+ ``total * 0.88 - inference_reserve``. A model whose weights exceed this budget cannot be held
88
+ resident even alone and will always stream; the runtime per-load budget can be lower still when
89
+ other models are resident, which is why the worker also reasons about reclaimable siblings.
90
+ """
91
+ reserve = compute_inference_reserve_mb(total_vram_mb, is_windows=is_windows, reserve_vram_gb=reserve_vram_gb)
92
+ return round(total_vram_mb * _WEIGHT_BUDGET_FRACTION) - reserve
File without changes
File without changes
File without changes