| name | metis-catalog-ingest |
| description | Stage a HuggingFace (or S3) MODEL or training DATASET into the demo Metis catalog so its weights/files land in SeaweedFS in the platform's standard, reusable format โ the same store the built-in models (57) and datasets (56) use, and the fast path (stages even 122B models). Use this instead of hand-downloading (clusterโHF egress is ~0.7โ3MB/s and ephemeral downloads are not reusable). Models: any type (LLM/VL/ diffusion). Datasets: HF source OR custom file upload. Auth = scripts/demo/demo_api.py cookie login. Use when "๋ชจ๋ธ/๋ฐ์ดํฐ์
์คํ
์ด์ง", "HF ๋ชจ๋ธยท๋ฐ์ดํฐ ๋ฑ๋ก", "์นดํ๋ก๊ทธ์ ์ถ๊ฐ", "๋ชจ๋ธ/๋ฐ์ดํฐ ์ธ์ ์คํธ", "SeaweedFS์ ์ฌ๋ ค์ค", "ํ์ต ๋ฐ์ดํฐ ์ถ๊ฐ", "register or stage a HF model/dataset on Metis", "add model or dataset to catalog", "ingest weights or training data". Do NOT use to serve/deploy a model (image โ metis-image-gen-serving; LLM fine-tune/serve โ metis-finetune-eval) or for IAM/access (metis-iam-access-grant). |
Metis Catalog Ingest (models + datasets)
Register a model or dataset with source_type set โ the platform ingests the HF/S3 source into
SeaweedFS (global/models/ for models; the dataset store for datasets) in the reusable format the
built-in catalog uses. Models & datasets share the SAME mechanism. Verified live 2026-07-22.
Step 1: Detect auth + project
cd "$(git rev-parse --show-toplevel)"
[ -f scripts/demo/demo_api.py ] && echo "demo_api OK" || echo "MISSING"
from demo_api import Client; c=Client("demo"); c.login() (cookie; creds in .secrets/).
Project id: c.get("/v1/metis/projects")[1]["data"] (ai-platform = e3885a23-โฆ).
Step 2: See what's already staged (reuse first โ don't re-download)
models = c.get(f"/v1/metis-hub/projects/{PID}/model-catalog/?page_size=100")[1]["data"]
datasets = c.get(f"/v1/metis-hub/projects/{PID}/dataset-catalog?page_size=100")[1]["data"]
Step 3: Ingest from HuggingFace (โ ๏ธ metis-hub prefix + TRAILING SLASH)
c.post(f"/v1/metis-hub/projects/{PID}/model-catalog/", body={
"model_id":"<org>/<repo>","model_name":"<name>","source_type":"huggingface",
"source_uri":"<org>/<repo>","revision":"main"})
c.post(f"/v1/metis-hub/projects/{PID}/dataset-catalog/", body={
"dataset_id":"<name>","name":"<name>","source_type":"huggingface",
"source_uri":"<hf-dataset-repo>","revision":"main"})
source_type โ {huggingface, s3} only (git rejected). Presence of source_type triggers ingest.
- Both routes: metis-hub prefix (not metis-fabric/ai-platform) AND a trailing slash on POST
(Fiber strict routing โ 404 otherwise).
GET (no slash) lists.
Step 4: Add a CUSTOM dataset by file upload (no HF source)
Resumable multipart under .../projects/{PID}/datasets/upload:
POST /upload/initiate {filename,...} โ GET /upload/{upload_id}/status โ POST /upload/{upload_id}/complete
(โ 202 async). Cancel: DELETE /upload/{upload_id}. Formats via GET /datasets/sample-templates
(SFT/DPO/GRPO/CPT JSONL + HF Arrow). Custom files land in the same dataset store, reusable next time.
Step 5: Monitor to available
m = c.get(f"/v1/metis-hub/projects/{PID}/model-catalog/{ID}")[1]
m["status"], m.get("ingest_status"), m.get("s3_path")
Trust the enriched ingest_status โ the /{id}/jobs list can return 0 for a non-admin role. No
byte-level progress is exposed. Retry/cancel: POST .../model-catalog/{id}/jobs/{job_id}/{retry|cancel}.
Step 6: Report
State id, ingest_status, and (when done) the SeaweedFS path. Downstream: models serve via
metis-image-gen-serving (image) / metis-finetune-eval (LLM); datasets feed TrainJobs / ML Studio.
Gotchas
- Route = metis-hub prefix + trailing slash on POST (both model- and dataset-catalog). Either wrong โ 404.
s3_path null until staged; poll ingest_status. Staging runs on a platform service (no visible K8s pod/GPU).
- Reuse over re-ingest: always Step 2 first โ 57 models + 56 datasets are already there.
- Cleanup is irreversible (
DELETE .../{id} + S3 global/models/ scoped delete) โ see [[destructive-batch-guard]].
- Do NOT hand-download 40GB+ as a fallback unless the catalog ingest is truly unavailable.
- โ ๏ธ Large-model ingest can FAIL on slow egress (observed 2026-07-23):
Qwen/Qwen-Image-2512
(~40GB) sat at ingest_status: downloading for ~4h then the catalog entry vanished (GETโ404,
count back to baseline) โ the ingest hit a duration/size ceiling over the clusterโHF ~3MB/s egress
and was cleaned up. The path is proven for the built-in catalog (mostly LLMs, likely staged from a
faster mirror), but a 40GB model over public-HF egress may not finish. Mitigations: verify it reaches
available (don't assume); prefer a quantized/smaller variant; or fix the cluster's HF egress. Watch
for the entry disappearing = failure, not "still downloading forever."