cortexgrid 0.2.89__tar.gz → 0.2.91__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.
- {cortexgrid-0.2.89 → cortexgrid-0.2.91}/PKG-INFO +1 -1
- {cortexgrid-0.2.89 → cortexgrid-0.2.91}/cortexgrid/model_serving.py +49 -1
- {cortexgrid-0.2.89 → cortexgrid-0.2.91}/pyproject.toml +1 -1
- {cortexgrid-0.2.89 → cortexgrid-0.2.91}/.gitignore +0 -0
- {cortexgrid-0.2.89 → cortexgrid-0.2.91}/LICENSE +0 -0
- {cortexgrid-0.2.89 → cortexgrid-0.2.91}/cortexgrid/__init__.py +0 -0
- {cortexgrid-0.2.89 → cortexgrid-0.2.91}/cortexgrid/_bundle.py +0 -0
- {cortexgrid-0.2.89 → cortexgrid-0.2.91}/cortexgrid/_ray_job_driver.py +0 -0
- {cortexgrid-0.2.89 → cortexgrid-0.2.91}/cortexgrid/_serve_entry.py +0 -0
- {cortexgrid-0.2.89 → cortexgrid-0.2.91}/cortexgrid/checkpoint.py +0 -0
- {cortexgrid-0.2.89 → cortexgrid-0.2.91}/cortexgrid/experiment.py +0 -0
- {cortexgrid-0.2.89 → cortexgrid-0.2.91}/cortexgrid/infra.py +0 -0
- {cortexgrid-0.2.89 → cortexgrid-0.2.91}/cortexgrid/jobs.py +0 -0
- {cortexgrid-0.2.89 → cortexgrid-0.2.91}/cortexgrid/mlflow_util.py +0 -0
- {cortexgrid-0.2.89 → cortexgrid-0.2.91}/cortexgrid/model_storage.py +0 -0
- {cortexgrid-0.2.89 → cortexgrid-0.2.91}/cortexgrid/py.typed +0 -0
- {cortexgrid-0.2.89 → cortexgrid-0.2.91}/cortexgrid/ray_util.py +0 -0
- {cortexgrid-0.2.89 → cortexgrid-0.2.91}/cortexgrid/s3_util.py +0 -0
- {cortexgrid-0.2.89 → cortexgrid-0.2.91}/cortexgrid/secrets.py +0 -0
- {cortexgrid-0.2.89 → cortexgrid-0.2.91}/cortexgrid/serve.py +0 -0
- {cortexgrid-0.2.89 → cortexgrid-0.2.91}/docs/cortexgrid/README.md +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: cortexgrid
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.91
|
|
4
4
|
Summary: Connect your ML code to the RoboLab compute cluster — Ray, MLflow, and S3
|
|
5
5
|
Project-URL: Homepage, https://github.com/robodatalab/cortexgrid
|
|
6
6
|
Project-URL: Repository, https://github.com/robodatalab/cortexgrid
|
|
@@ -21,6 +21,7 @@ from __future__ import annotations
|
|
|
21
21
|
import inspect
|
|
22
22
|
import json
|
|
23
23
|
import logging
|
|
24
|
+
import re
|
|
24
25
|
import shutil
|
|
25
26
|
import tempfile
|
|
26
27
|
import time
|
|
@@ -131,10 +132,17 @@ def bundle_class(
|
|
|
131
132
|
len(desc.local_files),
|
|
132
133
|
pip_requirements,
|
|
133
134
|
)
|
|
135
|
+
# Ray unpacks a remote (s3://) working_dir zip by stripping its
|
|
136
|
+
# top-level directory when there is exactly one, so a bundle of a single
|
|
137
|
+
# package (model_gateway/) would lose that directory and its import
|
|
138
|
+
# path. Zipping under code/ gives Ray that one directory to strip.
|
|
134
139
|
# make_archive returns the path it wrote. Rebuilding it with
|
|
135
140
|
# Path.with_suffix would cut dotted names ("Qwen2.5-0.5B" -> "Qwen2.zip").
|
|
136
141
|
archive = shutil.make_archive(
|
|
137
|
-
str(Path(tmp) / f"{family}__{suffix}"),
|
|
142
|
+
str(Path(tmp) / f"{family}__{suffix}"),
|
|
143
|
+
"zip",
|
|
144
|
+
root_dir=tmp,
|
|
145
|
+
base_dir=code_root.name,
|
|
138
146
|
)
|
|
139
147
|
bundle_url = upload(
|
|
140
148
|
archive,
|
|
@@ -397,3 +405,43 @@ def model_serving_status(
|
|
|
397
405
|
message=str(app.get("message", "")) or raw,
|
|
398
406
|
url=f"{get_ray_serve_uri()}{_route_prefix(family, suffix, run_name)}",
|
|
399
407
|
)
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
@dataclass
|
|
411
|
+
class ServingMessage:
|
|
412
|
+
"""One message the Ray Serve controller reports for a model's app. `source`
|
|
413
|
+
is "application" for the app-level message (e.g. the app failed to build)
|
|
414
|
+
or a deployment name for that deployment's message (e.g. its replicas
|
|
415
|
+
failed to start); `status` is the raw Ray Serve status of that source."""
|
|
416
|
+
|
|
417
|
+
source: str
|
|
418
|
+
status: str
|
|
419
|
+
message: str
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
# Ray colors parts of its messages (e.g. the serialization checker's "!!! FAIL")
|
|
423
|
+
# with ANSI escapes, which are noise outside a terminal.
|
|
424
|
+
_ANSI_ESCAPE = re.compile(r"\x1b\[[0-9;]*m")
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
def model_serving_messages(
|
|
428
|
+
family: str, suffix: str, run_name: str
|
|
429
|
+
) -> list[ServingMessage]:
|
|
430
|
+
"""Return the non-empty controller messages for a model's Serve app: the
|
|
431
|
+
app-level message first, then each deployment's. Empty when no app exists.
|
|
432
|
+
This is where Ray explains a DEPLOY_FAILED or UNHEALTHY app."""
|
|
433
|
+
app = get_serve_details().get("applications", {}).get(
|
|
434
|
+
_app_name(family, suffix, run_name)
|
|
435
|
+
)
|
|
436
|
+
if app is None:
|
|
437
|
+
return []
|
|
438
|
+
sources = [("application", app)] + list(app.get("deployments", {}).items())
|
|
439
|
+
return [
|
|
440
|
+
ServingMessage(
|
|
441
|
+
source=source,
|
|
442
|
+
status=str(details.get("status", "")),
|
|
443
|
+
message=_ANSI_ESCAPE.sub("", str(details["message"])),
|
|
444
|
+
)
|
|
445
|
+
for source, details in sources
|
|
446
|
+
if details.get("message")
|
|
447
|
+
]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|