fix: call Modal directly from the canonical Space
#6
by thangvip - opened
- README.md +4 -5
- docs/build-small-hackathon-article.md +5 -7
- src/compliment_forest/config.py +1 -6
README.md
CHANGED
|
@@ -113,11 +113,10 @@ hackathon's 32B total limit.
|
|
| 113 |
- **Training:** the MiniCPM and FLUX adapters, validation runs, and deployment
|
| 114 |
experiments used Modal.
|
| 115 |
|
| 116 |
-
Text and image inference scale independently. The canonical hackathon Space
|
| 117 |
-
serves the custom interface
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
services. No credential is stored in the public repository.
|
| 121 |
|
| 122 |
## Published Artifacts
|
| 123 |
|
|
|
|
| 113 |
- **Training:** the MiniCPM and FLUX adapters, validation runs, and deployment
|
| 114 |
experiments used Modal.
|
| 115 |
|
| 116 |
+
Text and image inference scale independently. The canonical hackathon Space is
|
| 117 |
+
a CPU orchestrator: it serves the custom interface, validates requests, streams
|
| 118 |
+
NDJSON progress, and HMAC-signs calls directly to the two Modal services. No
|
| 119 |
+
credential is stored in the public repository.
|
|
|
|
| 120 |
|
| 121 |
## Published Artifacts
|
| 122 |
|
docs/build-small-hackathon-article.md
CHANGED
|
@@ -133,10 +133,9 @@ animals, so the visual variety felt smaller than the style menu suggested.
|
|
| 133 |
|
| 134 |
## Modal as the GPU Layer
|
| 135 |
|
| 136 |
-
The canonical organization Space serves the custom interface
|
| 137 |
-
API response.
|
| 138 |
-
|
| 139 |
-
credential. Text and image workloads then run on separate Modal applications:
|
| 140 |
|
| 141 |
- MiniCPM4.1-8B on an A100 40GB endpoint
|
| 142 |
- FLUX.1-schnell plus the four style adapters on an A100 80GB endpoint
|
|
@@ -147,9 +146,8 @@ model from evicting the other and lets each service scale to zero
|
|
| 147 |
independently. The public repository contains no credentials.
|
| 148 |
|
| 149 |
Modal was also used for adapter training, validation grids, GGUF smoke tests,
|
| 150 |
-
and deployment experiments. The
|
| 151 |
-
|
| 152 |
-
remains visibly alive through both Hugging Face hops.
|
| 153 |
|
| 154 |
## Codex as an Engineering Partner
|
| 155 |
|
|
|
|
| 133 |
|
| 134 |
## Modal as the GPU Layer
|
| 135 |
|
| 136 |
+
The canonical organization Space serves the custom interface, validates
|
| 137 |
+
requests, and streams the API response. It holds an HMAC credential as a
|
| 138 |
+
private Space secret and calls two separate Modal applications directly:
|
|
|
|
| 139 |
|
| 140 |
- MiniCPM4.1-8B on an A100 40GB endpoint
|
| 141 |
- FLUX.1-schnell plus the four style adapters on an A100 80GB endpoint
|
|
|
|
| 146 |
independently. The public repository contains no credentials.
|
| 147 |
|
| 148 |
Modal was also used for adapter training, validation grids, GGUF smoke tests,
|
| 149 |
+
and deployment experiments. The organization Space signs requests with HMAC
|
| 150 |
+
and preserves the NDJSON stream so a long generation remains visibly alive.
|
|
|
|
| 151 |
|
| 152 |
## Codex as an Engineering Partner
|
| 153 |
|
src/compliment_forest/config.py
CHANGED
|
@@ -64,11 +64,6 @@ class AppConfig(BaseModel):
|
|
| 64 |
def from_env(cls) -> AppConfig:
|
| 65 |
trace_path = os.getenv("CF_TRACE_PATH")
|
| 66 |
hosted_space = bool(os.getenv("SPACE_ID"))
|
| 67 |
-
submission_upstream = (
|
| 68 |
-
"https://thangvip-compliment-forest.hf.space"
|
| 69 |
-
if os.getenv("SPACE_ID") == "build-small-hackathon/compliment-forest"
|
| 70 |
-
else None
|
| 71 |
-
)
|
| 72 |
default_text_backend = "transformers" if hosted_space else "demo"
|
| 73 |
default_image_backend = "zerogpu" if hosted_space else "demo"
|
| 74 |
return cls(
|
|
@@ -104,7 +99,7 @@ class AppConfig(BaseModel):
|
|
| 104 |
modal_image_endpoint=os.getenv("CF_MODAL_IMAGE_ENDPOINT"),
|
| 105 |
modal_music_endpoint=os.getenv("CF_MODAL_MUSIC_ENDPOINT"),
|
| 106 |
modal_signing_key=(os.getenv("CF_MODAL_SIGNING_KEY") or os.getenv("HF_TOKEN")),
|
| 107 |
-
upstream_space_url=os.getenv("CF_UPSTREAM_SPACE_URL")
|
| 108 |
local_files_only=os.getenv("CF_LOCAL_FILES_ONLY", "0") == "1",
|
| 109 |
default_seed=int(os.getenv("CF_DEFAULT_SEED", "3407")),
|
| 110 |
default_style=os.getenv("CF_DEFAULT_STYLE", "surprise"),
|
|
|
|
| 64 |
def from_env(cls) -> AppConfig:
|
| 65 |
trace_path = os.getenv("CF_TRACE_PATH")
|
| 66 |
hosted_space = bool(os.getenv("SPACE_ID"))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
default_text_backend = "transformers" if hosted_space else "demo"
|
| 68 |
default_image_backend = "zerogpu" if hosted_space else "demo"
|
| 69 |
return cls(
|
|
|
|
| 99 |
modal_image_endpoint=os.getenv("CF_MODAL_IMAGE_ENDPOINT"),
|
| 100 |
modal_music_endpoint=os.getenv("CF_MODAL_MUSIC_ENDPOINT"),
|
| 101 |
modal_signing_key=(os.getenv("CF_MODAL_SIGNING_KEY") or os.getenv("HF_TOKEN")),
|
| 102 |
+
upstream_space_url=os.getenv("CF_UPSTREAM_SPACE_URL"),
|
| 103 |
local_files_only=os.getenv("CF_LOCAL_FILES_ONLY", "0") == "1",
|
| 104 |
default_seed=int(os.getenv("CF_DEFAULT_SEED", "3407")),
|
| 105 |
default_style=os.getenv("CF_DEFAULT_STYLE", "surprise"),
|