Default Modal workflows to RTX Pro 6000
This commit is contained in:
@@ -159,7 +159,7 @@ If a rewritten graph could create a local scheduler cycle, Modal-Sync logs compa
|
||||
|
||||
Remote mode prefers a persistent deployed Modal app over ephemeral `app.run()` execution. First-run auto-deploy is enabled by default and can replace missing, stale, unversioned, or protocol-incompatible deployed apps. The extension does not create a persistent web endpoint.
|
||||
|
||||
Modal hardware is fixed at deploy time. Choose the target from `Modal` → `GPU`; the next remote run looks up or automatically builds the persistent Modal app dedicated to that GPU. The default `A100` target retains the configured base app name for compatibility, while other targets use a readable suffix such as `-gpu-b300`. GPU-specific app identity prevents a B300 request from contacting an existing A100 class merely to inspect its runtime fingerprint, which would otherwise provision the wrong GPU before the comparison could finish. The GPU apps continue to share the configured asset Volume and durable cache names. If you upgrade this node pack and expect changed remote behavior, redeploy the affected GPU app once so it picks up the new code and class options.
|
||||
Modal hardware is fixed at deploy time. Choose the target from `Modal` → `GPU`; the next remote run looks up or automatically builds the persistent Modal app dedicated to that GPU. New workflows default to `RTX-PRO-6000`. The legacy `A100` target retains the configured base app name for deployment compatibility, while every other target—including the new default—uses a readable suffix such as `-gpu-rtx-pro-6000` or `-gpu-b300`. GPU-specific app identity prevents one target from contacting an existing class for another GPU merely to inspect its runtime fingerprint. The GPU apps continue to share the configured asset Volume and durable cache names. If you upgrade this node pack and expect changed remote behavior, redeploy the affected GPU app once so it picks up the new code and class options.
|
||||
|
||||
The Modal image selects its pinned PyTorch wheel set from the workflow GPU target (or the `COMFY_MODAL_GPU` compatibility fallback). `B300` and `B200+` configurations use the CUDA 13.2 PyTorch and TorchVision wheels because Modal requires CUDA 13.1 or newer whenever a worker can be assigned a B300. Their TorchAudio layer uses the official CPU-only wheel with `--no-deps`; installing the ordinary PyPI wheel would add a CUDA 13.0 TorchAudio extension beside CUDA 13.2 PyTorch and make every GPU-snapshot container fail during import. ComfyUI's TorchAudio transforms continue to operate on Torch tensors, including CUDA tensors, without a TorchAudio CUDA extension. Other supported GPU types retain the complete CUDA 12.8 wheel set. Count suffixes such as `B300:2` remain supported through the environment fallback and are normalized before build selection; the workflow menu intentionally targets one GPU. Every ordered package layer is logged and recorded in the runtime fingerprint. The image build imports Torch, TorchVision, and TorchAudio and verifies `torch.version.cuda` before Modal deploys the app, so incompatible layers fail once during image construction instead of crash-looping snapshot workers.
|
||||
|
||||
@@ -263,7 +263,7 @@ Boolean values accept `1`, `true`, `yes`, `on`, `0`, `false`, `no`, and `off`.
|
||||
|
||||
| Variable | Default | Purpose |
|
||||
| --- | --- | --- |
|
||||
| `COMFY_MODAL_GPU` | `A100` | Compatibility fallback for workflows or API clients without `workflow.extra.comfy_modal.gpu`. The context-menu workflow selection is authoritative for normal UI runs and also selects the compatible pinned PyTorch CUDA wheel set. |
|
||||
| `COMFY_MODAL_GPU` | `RTX-PRO-6000` | Compatibility fallback for workflows or API clients without `workflow.extra.comfy_modal.gpu`. The context-menu workflow selection is authoritative for normal UI runs and also selects the compatible pinned PyTorch CUDA wheel set. |
|
||||
| `COMFY_MODAL_ENABLE_MEMORY_SNAPSHOT` | `true` | Enable Modal CPU memory snapshots. |
|
||||
| `COMFY_MODAL_ENABLE_GPU_MEMORY_SNAPSHOT` | `true` | Enable Modal GPU memory snapshots for profiled loader states. |
|
||||
| `COMFY_MODAL_SCALEDOWN_WINDOW` | `600` | Seconds to keep idle Modal containers warm. |
|
||||
|
||||
@@ -324,6 +324,7 @@
|
||||
- Modal GPU selection and the image's PyTorch CUDA wheel selection are one compatibility decision. B300 requires CUDA 13.1 or newer, so `B300` and upgradeable `B200+` specifications must select the CUDA 13.2 wheel index instead of inheriting the CUDA 12.8 default; count suffixes such as `B300:2` should not affect that choice. Record the resolved build in both logs and the runtime fingerprint so an incompatible image cannot masquerade as the expected deployment.
|
||||
- A runtime-fingerprint method on a GPU-backed Modal class is not a metadata-only probe: invoking it can provision that class's configured GPU. Resolve a GPU-specific persistent app name before lookup so a B300 workflow never contacts an A100 class, while retaining the stable instance-derived Volume and Dict names for shared assets and caches.
|
||||
- Global execution UI must retain the selected GPU as prompt-scoped state rather than reread the live workflow selection on every redraw. Users can change the workflow GPU while an older prompt is still running, and replayed backend status events need to carry the authoritative target so the pill cannot relabel active work.
|
||||
- The workflow/backend GPU default and the legacy base-app GPU identity are separate compatibility concerns. Changing the default to `RTX-PRO-6000` must not reassign an existing base app that may already contain an A100-backed class; retain A100 at the base app name and give the RTX default its own `-gpu-rtx-pro-6000` deployment.
|
||||
- A ComfyUI `LATENT` is not guaranteed to contain one plain tensor under `samples`. Multimodal nodes such as MiniMax H3 use `comfy.nested_tensor.NestedTensor` to retain ordered video and audio tensors, so boundary transport must encode that wrapper explicitly and reconstruct it after transferring each tensor member.
|
||||
- Remote status maps use executable prompt paths such as `105:14`, while an inner node opened in the subgraph canvas still has the local id `14`. Node decoration must resolve `workflowNodePath(node)` before reading phase, progress, cache, component, or badge state; otherwise only the outer subgraph instance can reflect descendant execution.
|
||||
- Files written by remote ComfyUI output nodes live on the Modal worker's ephemeral filesystem and must be captured before the invocation returns. Snapshot the effective `folder_paths` output tree immediately before execution, bundle new or replaced regular files into the durable invocation result, and materialize them locally with validated relative paths, content digests, atomic no-overwrite publication, and stable retry naming. Returning the encoded artifact is substantially smaller than returning its decoded `IMAGE` or `VIDEO` tensor.
|
||||
|
||||
@@ -464,6 +464,9 @@
|
||||
"groups": [],
|
||||
"config": {},
|
||||
"extra": {
|
||||
"comfy_modal": {
|
||||
"gpu": "RTX-PRO-6000"
|
||||
},
|
||||
"workflowRendererVersion": "LG",
|
||||
"ds": {
|
||||
"scale": 0.8779288479164423,
|
||||
|
||||
@@ -11,6 +11,11 @@ from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import Any, Protocol
|
||||
|
||||
if __package__:
|
||||
from .settings import DEFAULT_MODAL_GPU
|
||||
else: # pragma: no cover - the stable cloud entrypoint imports this module top-level.
|
||||
from settings import DEFAULT_MODAL_GPU
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
REMOTE_APP_PROTOCOL_VERSION = 6
|
||||
@@ -218,7 +223,7 @@ def select_remote_torch_build(modal_gpu: str) -> RemoteTorchBuild:
|
||||
)
|
||||
|
||||
|
||||
def remote_torch_packages(modal_gpu: str = "A100") -> tuple[str, ...]:
|
||||
def remote_torch_packages(modal_gpu: str = DEFAULT_MODAL_GPU) -> tuple[str, ...]:
|
||||
"""Return the exact PyTorch package set for one Modal GPU specification."""
|
||||
return select_remote_torch_build(modal_gpu).packages
|
||||
|
||||
|
||||
+6
-5
@@ -44,7 +44,8 @@ MODAL_GPU_TYPES = (
|
||||
)
|
||||
WORKFLOW_MODAL_CONFIG_KEY = "comfy_modal"
|
||||
WORKFLOW_MODAL_GPU_KEY = "gpu"
|
||||
_DEFAULT_MODAL_GPU = "A100"
|
||||
DEFAULT_MODAL_GPU = "RTX-PRO-6000"
|
||||
_LEGACY_BASE_APP_GPU = "A100"
|
||||
_MODAL_APP_NAME_MAX_LENGTH = 64
|
||||
_MODAL_GPU_SLUG_MAX_LENGTH = 28
|
||||
|
||||
@@ -124,7 +125,7 @@ class ModalSyncSettings:
|
||||
bridge_inline_max_bytes: int = 4 * 1024 * 1024
|
||||
invocation_result_inline_max_bytes: int = 4 * 1024 * 1024
|
||||
terminate_container_on_error: bool = True
|
||||
modal_gpu: str = "A100"
|
||||
modal_gpu: str = DEFAULT_MODAL_GPU
|
||||
scaledown_window_seconds: int = 600
|
||||
min_containers: int = 0
|
||||
max_containers: int | None = None
|
||||
@@ -201,8 +202,8 @@ def _modal_gpu_app_slug(modal_gpu: str) -> str:
|
||||
|
||||
def modal_deployment_app_name(settings: ModalSyncSettings) -> str:
|
||||
"""Return the persistent Modal app name dedicated to the configured GPU target."""
|
||||
modal_gpu = str(getattr(settings, "modal_gpu", _DEFAULT_MODAL_GPU)).strip()
|
||||
if modal_gpu.upper() == _DEFAULT_MODAL_GPU:
|
||||
modal_gpu = str(getattr(settings, "modal_gpu", DEFAULT_MODAL_GPU)).strip()
|
||||
if modal_gpu.upper() == _LEGACY_BASE_APP_GPU:
|
||||
return settings.app_name
|
||||
|
||||
suffix = f"-gpu-{_modal_gpu_app_slug(modal_gpu)}"
|
||||
@@ -450,7 +451,7 @@ def _get_settings_cached(
|
||||
),
|
||||
terminate_container_on_error=_read_bool_env("COMFY_MODAL_TERMINATE_CONTAINER_ON_ERROR")
|
||||
is not False,
|
||||
modal_gpu=os.getenv("COMFY_MODAL_GPU", "A100").strip() or "A100",
|
||||
modal_gpu=os.getenv("COMFY_MODAL_GPU", DEFAULT_MODAL_GPU).strip() or DEFAULT_MODAL_GPU,
|
||||
scaledown_window_seconds=_read_int_env("COMFY_MODAL_SCALEDOWN_WINDOW", 600),
|
||||
min_containers=_read_int_env("COMFY_MODAL_MIN_CONTAINERS", 0),
|
||||
max_containers=_read_optional_int_env("COMFY_MODAL_MAX_CONTAINERS"),
|
||||
|
||||
@@ -532,8 +532,8 @@ const workflowGraph = {
|
||||
};
|
||||
globalThis.__modalAppStub.rootGraph = workflowGraph;
|
||||
globalThis.__modalAppStub.graph.rootGraph = workflowGraph;
|
||||
assert.equal(modalToggle.selectedModalGpu(), "A100");
|
||||
assert.equal(workflowGraph.extra.comfy_modal.gpu, "A100");
|
||||
assert.equal(modalToggle.selectedModalGpu(), "RTX-PRO-6000");
|
||||
assert.equal(workflowGraph.extra.comfy_modal.gpu, "RTX-PRO-6000");
|
||||
|
||||
modalToggle.setSelectedModalGpu("B300");
|
||||
assert.equal(modalToggle.selectedModalGpu(), "B300");
|
||||
|
||||
@@ -21,6 +21,8 @@ from typing import Any, Iterator
|
||||
|
||||
import pytest
|
||||
|
||||
DEFAULT_TEST_DEPLOYMENT_APP_NAME = "comfy-modal-sync-gpu-rtx-pro-6000"
|
||||
|
||||
|
||||
class _FakeOriginalNode:
|
||||
"""Simple fake legacy node for proxy signature mirroring."""
|
||||
@@ -3983,7 +3985,7 @@ def test_modal_cloud_existing_app_guard_uses_non_creating_sdk_lookup(
|
||||
with pytest.raises(modal_cloud_module.ExistingModalAppError) as exc_info:
|
||||
modal_cloud_module._guard_against_existing_modal_app(settings, fake_modal)
|
||||
|
||||
assert lookup_calls == [("comfy-modal-sync", False)]
|
||||
assert lookup_calls == [(DEFAULT_TEST_DEPLOYMENT_APP_NAME, False)]
|
||||
assert "Delete the existing app" in str(exc_info.value)
|
||||
assert "COMFY_MODAL_GPU" in str(exc_info.value)
|
||||
|
||||
@@ -4034,7 +4036,7 @@ def test_modal_cloud_existing_app_guard_falls_back_to_cli_json(
|
||||
completed = subprocess.CompletedProcess(
|
||||
args=["modal", "app", "list", "--json"],
|
||||
returncode=0,
|
||||
stdout=json.dumps([{"name": "other"}, {"name": "comfy-modal-sync"}]),
|
||||
stdout=json.dumps([{"name": "other"}, {"name": DEFAULT_TEST_DEPLOYMENT_APP_NAME}]),
|
||||
stderr="",
|
||||
)
|
||||
observed_commands: list[list[str]] = []
|
||||
@@ -4471,7 +4473,7 @@ def test_remote_modal_auto_deploys_missing_app_by_default(
|
||||
remote_modal_app_module._MODAL_REMOTE_APP_VERSION_OK.clear()
|
||||
|
||||
assert response == b"remote-response"
|
||||
assert deploy_calls == [("comfy-modal-sync", None)]
|
||||
assert deploy_calls == [(DEFAULT_TEST_DEPLOYMENT_APP_NAME, None)]
|
||||
assert [
|
||||
(event["phase"], event["status_message"])
|
||||
for event in status_events
|
||||
@@ -4645,7 +4647,9 @@ def test_remote_modal_redeploys_when_cached_app_was_deleted(
|
||||
remote_modal_app_module.get_settings.cache_clear()
|
||||
remote_modal_app_module._MODAL_AUTO_DEPLOY_STATES.clear()
|
||||
remote_modal_app_module._MODAL_REMOTE_APP_VERSION_OK.clear()
|
||||
remote_modal_app_module._MODAL_AUTO_DEPLOY_STATES[("comfy-modal-sync", "main")] = (
|
||||
remote_modal_app_module._MODAL_AUTO_DEPLOY_STATES[
|
||||
(DEFAULT_TEST_DEPLOYMENT_APP_NAME, "main")
|
||||
] = (
|
||||
remote_modal_app_module._ModalAutoDeployState(ready=True)
|
||||
)
|
||||
try:
|
||||
@@ -4659,7 +4663,7 @@ def test_remote_modal_redeploys_when_cached_app_was_deleted(
|
||||
remote_modal_app_module._MODAL_REMOTE_APP_VERSION_OK.clear()
|
||||
|
||||
assert response == b"remote-response"
|
||||
assert deploy_calls == [("comfy-modal-sync", "main")]
|
||||
assert deploy_calls == [(DEFAULT_TEST_DEPLOYMENT_APP_NAME, "main")]
|
||||
|
||||
|
||||
def test_remote_modal_redeploys_when_deployed_handle_disappears_during_payload_invoke(
|
||||
@@ -4755,7 +4759,7 @@ def test_remote_modal_redeploys_when_deployed_handle_disappears_during_payload_i
|
||||
remote_modal_app_module._MODAL_REMOTE_APP_VERSION_OK.clear()
|
||||
|
||||
assert response == b"remote-response"
|
||||
assert deploy_calls == [("comfy-modal-sync", "main")]
|
||||
assert deploy_calls == [(DEFAULT_TEST_DEPLOYMENT_APP_NAME, "main")]
|
||||
|
||||
|
||||
def test_remote_modal_redeploys_when_deployed_handle_disappears_during_warmup(
|
||||
@@ -4849,7 +4853,7 @@ def test_remote_modal_redeploys_when_deployed_handle_disappears_during_warmup(
|
||||
remote_modal_app_module._MODAL_REMOTE_APP_VERSION_OK.clear()
|
||||
|
||||
assert response == {"component_id": "component-1::warmup:0"}
|
||||
assert deploy_calls == [("comfy-modal-sync", "main")]
|
||||
assert deploy_calls == [(DEFAULT_TEST_DEPLOYMENT_APP_NAME, "main")]
|
||||
|
||||
|
||||
def test_remote_modal_replaces_out_of_date_deployed_app(
|
||||
@@ -4958,8 +4962,8 @@ def test_remote_modal_replaces_out_of_date_deployed_app(
|
||||
remote_modal_app_module._MODAL_REMOTE_APP_VERSION_OK.clear()
|
||||
|
||||
assert response == b"remote-response"
|
||||
assert stop_calls == ["comfy-modal-sync"]
|
||||
assert deploy_calls == [("comfy-modal-sync", "main")]
|
||||
assert stop_calls == [DEFAULT_TEST_DEPLOYMENT_APP_NAME]
|
||||
assert deploy_calls == [(DEFAULT_TEST_DEPLOYMENT_APP_NAME, "main")]
|
||||
|
||||
|
||||
def test_remote_modal_stops_app_through_experimental_sdk(
|
||||
@@ -5259,7 +5263,7 @@ def test_remote_modal_auto_deploy_is_shared_across_concurrent_first_run_callers(
|
||||
assert thread_errors == []
|
||||
assert payload_response == [b"remote-response"]
|
||||
assert warmup_response == [{"component_id": "component-1"}]
|
||||
assert deploy_calls == [("comfy-modal-sync", "main")]
|
||||
assert deploy_calls == [(DEFAULT_TEST_DEPLOYMENT_APP_NAME, "main")]
|
||||
|
||||
|
||||
def test_lookup_deployed_remote_engine_excludes_affinity_from_modal_class_parameters(
|
||||
@@ -5278,7 +5282,7 @@ def test_lookup_deployed_remote_engine_excludes_affinity_from_modal_class_parame
|
||||
@staticmethod
|
||||
def from_name(app_name: str, class_name: str) -> Any:
|
||||
"""Return a factory that records the provided class parameters."""
|
||||
assert app_name == "comfy-modal-sync"
|
||||
assert app_name == DEFAULT_TEST_DEPLOYMENT_APP_NAME
|
||||
assert class_name == "RemoteEngine"
|
||||
|
||||
def build_remote_engine(**kwargs: Any) -> dict[str, Any]:
|
||||
@@ -5367,7 +5371,7 @@ def test_lookup_deployed_remote_engine_passes_snapshot_profile_parameter_for_gpu
|
||||
@staticmethod
|
||||
def from_name(app_name: str, class_name: str) -> Any:
|
||||
"""Return a factory that records the provided class parameters."""
|
||||
assert app_name == "comfy-modal-sync"
|
||||
assert app_name == DEFAULT_TEST_DEPLOYMENT_APP_NAME
|
||||
assert class_name == "RemoteEngine"
|
||||
|
||||
def build_remote_engine(**kwargs: Any) -> dict[str, Any]:
|
||||
@@ -5430,7 +5434,7 @@ def test_lookup_deployed_remote_engine_stores_existing_snapshot_profile_record_w
|
||||
@staticmethod
|
||||
def from_name(app_name: str, class_name: str) -> Any:
|
||||
"""Return a factory that records the provided class parameters."""
|
||||
assert app_name == "comfy-modal-sync"
|
||||
assert app_name == DEFAULT_TEST_DEPLOYMENT_APP_NAME
|
||||
assert class_name == "RemoteEngine"
|
||||
|
||||
def build_remote_engine(**kwargs: Any) -> dict[str, Any]:
|
||||
@@ -5491,7 +5495,7 @@ def test_lookup_deployed_remote_engine_reuses_worker_pool_slots_across_prompt_se
|
||||
@staticmethod
|
||||
def from_name(app_name: str, class_name: str) -> Any:
|
||||
"""Return a factory that records the provided class parameters."""
|
||||
assert app_name == "comfy-modal-sync"
|
||||
assert app_name == DEFAULT_TEST_DEPLOYMENT_APP_NAME
|
||||
assert class_name == "RemoteEngine"
|
||||
|
||||
def build_remote_engine(**kwargs: Any) -> dict[str, Any]:
|
||||
@@ -5569,7 +5573,7 @@ def test_lookup_deployed_remote_engine_shares_profiled_identity_across_lane_over
|
||||
@staticmethod
|
||||
def from_name(app_name: str, class_name: str) -> Any:
|
||||
"""Return a factory that records the provided class parameters."""
|
||||
assert app_name == "comfy-modal-sync"
|
||||
assert app_name == DEFAULT_TEST_DEPLOYMENT_APP_NAME
|
||||
assert class_name == "RemoteEngine"
|
||||
|
||||
def build_remote_engine(**kwargs: Any) -> dict[str, Any]:
|
||||
|
||||
@@ -62,6 +62,7 @@ def test_modal_test_workflow_captures_known_working_remote_component() -> None:
|
||||
|
||||
assert workflow_path.exists()
|
||||
assert workflow["version"] == 0.4
|
||||
assert workflow["extra"]["comfy_modal"]["gpu"] == "RTX-PRO-6000"
|
||||
assert node_types_by_id[2] == "KSampler"
|
||||
assert node_types_by_id[7] == "UNETLoader"
|
||||
assert node_types_by_id[11] == "CLIPLoader"
|
||||
|
||||
@@ -302,5 +302,6 @@ def test_local_remote_result_materializer_returns_node_outputs(
|
||||
|
||||
assert outputs == b"serialized-outputs"
|
||||
assert (
|
||||
output_directory / "remote-ez7utL15S7Y-786123456-render.mp4"
|
||||
output_directory
|
||||
/ "remote-ez7utL15S7Y-gpu-rtx-pro-6000-786123456-render.mp4"
|
||||
).read_bytes() == b"encoded-video"
|
||||
|
||||
@@ -61,6 +61,7 @@ def test_remote_environment_is_fully_pinned(runtime_environment_module: Any) ->
|
||||
runtime_packages = runtime_environment_module.remote_runtime_packages()
|
||||
torch_packages = runtime_environment_module.remote_torch_packages()
|
||||
|
||||
assert runtime_environment_module.DEFAULT_MODAL_GPU == "RTX-PRO-6000"
|
||||
assert runtime_environment_module.REMOTE_APP_PROTOCOL_VERSION >= 5
|
||||
assert runtime_environment_module.REMOTE_PYTHON_VERSION == "3.11"
|
||||
assert apt_packages == ("libgl1", "libglib2.0-0")
|
||||
|
||||
+20
-2
@@ -61,6 +61,20 @@ def test_settings_reads_modal_gpu_override(
|
||||
assert settings.modal_gpu == "L40S"
|
||||
|
||||
|
||||
def test_settings_defaults_modal_gpu_to_rtx_pro_6000(
|
||||
settings_module: Any,
|
||||
) -> None:
|
||||
"""Backend settings should use the same RTX default as the workflow UI."""
|
||||
settings_module.get_settings.cache_clear()
|
||||
try:
|
||||
settings = settings_module.get_settings()
|
||||
finally:
|
||||
settings_module.get_settings.cache_clear()
|
||||
|
||||
assert settings_module.DEFAULT_MODAL_GPU == "RTX-PRO-6000"
|
||||
assert settings.modal_gpu == "RTX-PRO-6000"
|
||||
|
||||
|
||||
def test_modal_gpu_from_workflow_prefers_saved_selection(settings_module: Any) -> None:
|
||||
"""A saved workflow GPU should override the process-level fallback."""
|
||||
workflow = {"extra": {"comfy_modal": {"gpu": "B300"}}}
|
||||
@@ -98,18 +112,22 @@ def test_settings_for_modal_gpu_preserves_other_runtime_settings(settings_module
|
||||
assert overridden_settings.volume_name == base_settings.volume_name
|
||||
|
||||
|
||||
def test_modal_deployment_app_name_isolates_non_default_gpu_targets(
|
||||
def test_modal_deployment_app_name_isolates_gpu_targets_from_legacy_a100_app(
|
||||
settings_module: Any,
|
||||
) -> None:
|
||||
"""Each non-default GPU should use a persistent app that cannot probe an A100 app."""
|
||||
"""The RTX default should not probe the legacy A100 app retained at the base name."""
|
||||
base_settings = settings_module.get_settings()
|
||||
|
||||
rtx_settings = settings_module.settings_for_modal_gpu(base_settings, "RTX-PRO-6000")
|
||||
a100_settings = settings_module.settings_for_modal_gpu(base_settings, "A100")
|
||||
b300_settings = settings_module.settings_for_modal_gpu(base_settings, "B300")
|
||||
h100_settings = settings_module.settings_for_modal_gpu(base_settings, "H100")
|
||||
priority_h100_settings = settings_module.settings_for_modal_gpu(base_settings, "H100!")
|
||||
|
||||
assert settings_module.modal_deployment_app_name(a100_settings) == base_settings.app_name
|
||||
assert settings_module.modal_deployment_app_name(rtx_settings) == (
|
||||
f"{base_settings.app_name}-gpu-rtx-pro-6000"
|
||||
)
|
||||
assert settings_module.modal_deployment_app_name(b300_settings) == (
|
||||
f"{base_settings.app_name}-gpu-b300"
|
||||
)
|
||||
|
||||
@@ -63,6 +63,13 @@ def test_global_modal_status_badge_is_installed() -> None:
|
||||
assert "function promptActiveNodeIsLive(promptId)" in source
|
||||
|
||||
|
||||
def test_frontend_defaults_modal_gpu_to_rtx_pro_6000() -> None:
|
||||
"""Unsaved workflows should receive the requested RTX GPU default."""
|
||||
source = _modal_toggle_source()
|
||||
|
||||
assert 'const DEFAULT_MODAL_GPU = "RTX-PRO-6000";' in source
|
||||
|
||||
|
||||
def test_empty_modal_status_events_do_not_show_global_pill() -> None:
|
||||
"""Queue requests without Modal-enabled nodes should not create global Modal UI state."""
|
||||
source = _modal_toggle_source()
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ const COMFY_HISTORY_ROUTE = "/history";
|
||||
const INTERNAL_NODE_PREFIX = "ModalUniversalExecutor";
|
||||
const WORKFLOW_MODAL_CONFIG_KEY = "comfy_modal";
|
||||
const WORKFLOW_MODAL_GPU_KEY = "gpu";
|
||||
const DEFAULT_MODAL_GPU = "A100";
|
||||
const DEFAULT_MODAL_GPU = "RTX-PRO-6000";
|
||||
const MODAL_GPU_TYPES = [
|
||||
"T4",
|
||||
"L4",
|
||||
|
||||
Reference in New Issue
Block a user