Spaces:
Running on Zero
Running on Zero
Michael Stattelman commited on
Commit ·
6012dcc
1
Parent(s): 43c3b3c
Add application file
Browse files- README.md +6 -4
- app/main.py +1 -1
- app/registry.py +6 -3
- app/static/index.html +2 -1
- docker-compose.yml +1 -0
- tests/test_api.py +8 -5
- tests/test_links.py +3 -2
- tests/test_registry.py +27 -16
README.md
CHANGED
|
@@ -14,9 +14,10 @@ pinned: false
|
|
| 14 |
|
| 15 |
A self-hosted web lab that puts decision models on the same decisions and compares their answers, confidence and speed:
|
| 16 |
|
| 17 |
-
- **
|
| 18 |
- **LightDec_Arthur**: [Falconsai/LightDec_Arthur](https://huggingface.co/Falconsai/LightDec_Arthur), the byte-level Arthur model (about 12M parameters). Only its `config.json` and `model.safetensors` are downloaded; the code that runs it ships with DecisionLab, copied verbatim from the arthur_v0_8_0 notebook.
|
| 19 |
- **LightDec_V2**: [Falconsai/LightDec_V2](https://huggingface.co/Falconsai/LightDec_V2), FalconDec on the Ettin-150M encoder (about 160M parameters). Its `falcondec_modeling.py` runs only if its sha256 is on the allowlist; otherwise its card shows the hash and how to trust it.
|
|
|
|
| 20 |
- **Laya**: [convaiinnovations/laya](https://huggingface.co/convaiinnovations/laya), by Convai Innovations, ModernBERT-large, 421M parameters, Apache-2.0.
|
| 21 |
- **Every model in the `models` folder**, added after those and marked "(local)":
|
| 22 |
- **LightDec (FalconDec) models**: a folder with a `falcondec_config.json`, named from that config.
|
|
@@ -52,7 +53,7 @@ docker build -t decisionlab .
|
|
| 52 |
docker run -d --name DecisionLab -p 9910:9910 -v decisionlab-hf:/data/hf -v "${PWD}\models:/models:ro" decisionlab
|
| 53 |
```
|
| 54 |
|
| 55 |
-
The first start downloads the
|
| 56 |
|
| 57 |
### NVIDIA GPU
|
| 58 |
|
|
@@ -80,11 +81,11 @@ cd <your-space>
|
|
| 80 |
git lfs install
|
| 81 |
# copy the contents of this DecisionLab folder into it (not the folder itself), then:
|
| 82 |
git add .
|
| 83 |
-
git commit -m "DecisionLab 2.
|
| 84 |
git push
|
| 85 |
```
|
| 86 |
|
| 87 |
-
The Space downloads the
|
| 88 |
|
| 89 |
Call it from Python:
|
| 90 |
|
|
@@ -111,6 +112,7 @@ The plain HTTP API works on the Space too, at `https://<your-user>-<your-space>.
|
|
| 111 |
| `LIGHTDEC_VARIANT` | `fp16` | `fp16` (each model folder itself) or `int8` (its `compact-int8` subfolder, dequantised on load), for every discovered model |
|
| 112 |
| `LIGHTDEC_ARTHUR_REPO` | `Falconsai/LightDec_Arthur` | Hub repo shown as LightDec_Arthur |
|
| 113 |
| `LIGHTDEC_V2_REPO` | `Falconsai/LightDec_V2` | Hub repo shown as LightDec_V2 |
|
|
|
|
| 114 |
| `LAYA_REPO` | `convaiinnovations/laya` | Laya checkpoint loaded with `laya.load()` |
|
| 115 |
| `LAYA_FALLBACK_REPO` | – | Optional second Laya repo, tried if the first fails |
|
| 116 |
| `LOAD_ORDER` | comparison order | Which models to load at start, in order, by key (see `/api/status`) |
|
|
|
|
| 14 |
|
| 15 |
A self-hosted web lab that puts decision models on the same decisions and compares their answers, confidence and speed:
|
| 16 |
|
| 17 |
+
- **Four models from the Hugging Face Hub**, in this order:
|
| 18 |
- **LightDec_Arthur**: [Falconsai/LightDec_Arthur](https://huggingface.co/Falconsai/LightDec_Arthur), the byte-level Arthur model (about 12M parameters). Only its `config.json` and `model.safetensors` are downloaded; the code that runs it ships with DecisionLab, copied verbatim from the arthur_v0_8_0 notebook.
|
| 19 |
- **LightDec_V2**: [Falconsai/LightDec_V2](https://huggingface.co/Falconsai/LightDec_V2), FalconDec on the Ettin-150M encoder (about 160M parameters). Its `falcondec_modeling.py` runs only if its sha256 is on the allowlist; otherwise its card shows the hash and how to trust it.
|
| 20 |
+
- **Enterprise Reflux Laya V2.1**: [yasserrmd/enterprise-reflux-laya-v21](https://huggingface.co/yasserrmd/enterprise-reflux-laya-v21), a Laya fine-tune for ranking enterprise actions (ModernBERT-large, like Laya), loaded with the same `laya` runtime. Its model card marks it a research prototype, not for production.
|
| 21 |
- **Laya**: [convaiinnovations/laya](https://huggingface.co/convaiinnovations/laya), by Convai Innovations, ModernBERT-large, 421M parameters, Apache-2.0.
|
| 22 |
- **Every model in the `models` folder**, added after those and marked "(local)":
|
| 23 |
- **LightDec (FalconDec) models**: a folder with a `falcondec_config.json`, named from that config.
|
|
|
|
| 53 |
docker run -d --name DecisionLab -p 9910:9910 -v decisionlab-hf:/data/hf -v "${PWD}\models:/models:ro" decisionlab
|
| 54 |
```
|
| 55 |
|
| 56 |
+
The first start downloads the four Hub models (about 2 GB) into the `decisionlab-hf` volume. The page shows each model's loading progress, and later starts load from the cache in seconds.
|
| 57 |
|
| 58 |
### NVIDIA GPU
|
| 59 |
|
|
|
|
| 81 |
git lfs install
|
| 82 |
# copy the contents of this DecisionLab folder into it (not the folder itself), then:
|
| 83 |
git add .
|
| 84 |
+
git commit -m "DecisionLab 2.2.0"
|
| 85 |
git push
|
| 86 |
```
|
| 87 |
|
| 88 |
+
The Space downloads the four Hub models on first start. Model folders you put in `models/` are loaded too; their weights go through Git LFS (`.gitattributes`).
|
| 89 |
|
| 90 |
Call it from Python:
|
| 91 |
|
|
|
|
| 112 |
| `LIGHTDEC_VARIANT` | `fp16` | `fp16` (each model folder itself) or `int8` (its `compact-int8` subfolder, dequantised on load), for every discovered model |
|
| 113 |
| `LIGHTDEC_ARTHUR_REPO` | `Falconsai/LightDec_Arthur` | Hub repo shown as LightDec_Arthur |
|
| 114 |
| `LIGHTDEC_V2_REPO` | `Falconsai/LightDec_V2` | Hub repo shown as LightDec_V2 |
|
| 115 |
+
| `REFLUX_LAYA_REPO` | `yasserrmd/enterprise-reflux-laya-v21` | Hub repo shown as Enterprise Reflux Laya V2.1 (a Laya checkpoint) |
|
| 116 |
| `LAYA_REPO` | `convaiinnovations/laya` | Laya checkpoint loaded with `laya.load()` |
|
| 117 |
| `LAYA_FALLBACK_REPO` | – | Optional second Laya repo, tried if the first fails |
|
| 118 |
| `LOAD_ORDER` | comparison order | Which models to load at start, in order, by key (see `/api/status`) |
|
app/main.py
CHANGED
|
@@ -27,7 +27,7 @@ MAX_BODY_BYTES = int(os.getenv("MAX_BODY_BYTES", str(256 * 1024)))
|
|
| 27 |
DECIDE_SLOTS = Gate(int(os.getenv("MAX_PENDING_DECIDES", "4"))) # DL-SA-004
|
| 28 |
|
| 29 |
# DL-SA-007: no /docs, /redoc or /openapi.json
|
| 30 |
-
VERSION = "2.
|
| 31 |
PAGE = stamp_assets((STATIC / "index.html").read_text(encoding="utf-8"), VERSION)
|
| 32 |
|
| 33 |
|
|
|
|
| 27 |
DECIDE_SLOTS = Gate(int(os.getenv("MAX_PENDING_DECIDES", "4"))) # DL-SA-004
|
| 28 |
|
| 29 |
# DL-SA-007: no /docs, /redoc or /openapi.json
|
| 30 |
+
VERSION = "2.2.0"
|
| 31 |
PAGE = stamp_assets((STATIC / "index.html").read_text(encoding="utf-8"), VERSION)
|
| 32 |
|
| 33 |
|
app/registry.py
CHANGED
|
@@ -1,8 +1,9 @@
|
|
| 1 |
"""Which models DecisionLab compares.
|
| 2 |
|
| 3 |
-
First the operator's
|
| 4 |
LightDec_Arthur Falconsai/LightDec_Arthur (Arthur; code ships with DecisionLab)
|
| 5 |
LightDec_V2 Falconsai/LightDec_V2 (FalconDec; its modeling code must be on the allowlist)
|
|
|
|
| 6 |
Laya convaiinnovations/laya
|
| 7 |
Then every model folder found in the models directory, named "... (local)".
|
| 8 |
|
|
@@ -83,19 +84,21 @@ def discover(models_dir: str) -> list[tuple[Path, str]]:
|
|
| 83 |
|
| 84 |
|
| 85 |
def model_specs(env: Mapping[str, str]) -> list[dict]:
|
| 86 |
-
"""One dict per model, in the order the UI shows them: the
|
| 87 |
variant = _variant(env, "LIGHTDEC_VARIANT")
|
| 88 |
specs = [
|
| 89 |
{"key": "lightdec_arthur", "name": "LightDec_Arthur", "kind": "arthur", "side": PALETTE[0], "source": "hub",
|
| 90 |
"repo": env.get("LIGHTDEC_ARTHUR_REPO") or "Falconsai/LightDec_Arthur"},
|
| 91 |
{"key": "lightdec_v2", "name": "LightDec_V2", "kind": "lightdec", "side": PALETTE[1], "source": "hub",
|
| 92 |
"repo": env.get("LIGHTDEC_V2_REPO") or "Falconsai/LightDec_V2", "revision": None, "variant": variant},
|
|
|
|
|
|
|
| 93 |
{"key": "laya", "name": "Laya", "kind": "laya", "side": "laya",
|
| 94 |
"repo": env.get("LAYA_REPO") or "convaiinnovations/laya",
|
| 95 |
"fallback_repo": env.get("LAYA_FALLBACK_REPO", "")},
|
| 96 |
]
|
| 97 |
used = {s["key"] for s in specs}
|
| 98 |
-
for i, (folder, kind) in enumerate(discover(env.get("MODELS_DIR") or DEFAULT_MODELS_DIR), start=
|
| 99 |
key, n = _slug(folder.name), 2
|
| 100 |
while key in used:
|
| 101 |
key, n = f"{_slug(folder.name)}_{n}", n + 1
|
|
|
|
| 1 |
"""Which models DecisionLab compares.
|
| 2 |
|
| 3 |
+
First the operator's Hugging Face models, in this order (rulings 2026-09-28 and 2026-09-30):
|
| 4 |
LightDec_Arthur Falconsai/LightDec_Arthur (Arthur; code ships with DecisionLab)
|
| 5 |
LightDec_V2 Falconsai/LightDec_V2 (FalconDec; its modeling code must be on the allowlist)
|
| 6 |
+
Enterprise Reflux Laya V2.1 yasserrmd/enterprise-reflux-laya-v21 (a Laya fine-tune; loaded with laya 0.3.20)
|
| 7 |
Laya convaiinnovations/laya
|
| 8 |
Then every model folder found in the models directory, named "... (local)".
|
| 9 |
|
|
|
|
| 84 |
|
| 85 |
|
| 86 |
def model_specs(env: Mapping[str, str]) -> list[dict]:
|
| 87 |
+
"""One dict per model, in the order the UI shows them: the four Hub models, then the models folder."""
|
| 88 |
variant = _variant(env, "LIGHTDEC_VARIANT")
|
| 89 |
specs = [
|
| 90 |
{"key": "lightdec_arthur", "name": "LightDec_Arthur", "kind": "arthur", "side": PALETTE[0], "source": "hub",
|
| 91 |
"repo": env.get("LIGHTDEC_ARTHUR_REPO") or "Falconsai/LightDec_Arthur"},
|
| 92 |
{"key": "lightdec_v2", "name": "LightDec_V2", "kind": "lightdec", "side": PALETTE[1], "source": "hub",
|
| 93 |
"repo": env.get("LIGHTDEC_V2_REPO") or "Falconsai/LightDec_V2", "revision": None, "variant": variant},
|
| 94 |
+
{"key": "enterprise_reflux_laya_v21", "name": "Enterprise Reflux Laya V2.1", "kind": "laya", "side": PALETTE[2],
|
| 95 |
+
"repo": env.get("REFLUX_LAYA_REPO") or "yasserrmd/enterprise-reflux-laya-v21", "fallback_repo": ""},
|
| 96 |
{"key": "laya", "name": "Laya", "kind": "laya", "side": "laya",
|
| 97 |
"repo": env.get("LAYA_REPO") or "convaiinnovations/laya",
|
| 98 |
"fallback_repo": env.get("LAYA_FALLBACK_REPO", "")},
|
| 99 |
]
|
| 100 |
used = {s["key"] for s in specs}
|
| 101 |
+
for i, (folder, kind) in enumerate(discover(env.get("MODELS_DIR") or DEFAULT_MODELS_DIR), start=3):
|
| 102 |
key, n = _slug(folder.name), 2
|
| 103 |
while key in used:
|
| 104 |
key, n = f"{_slug(folder.name)}_{n}", n + 1
|
app/static/index.html
CHANGED
|
@@ -42,7 +42,7 @@
|
|
| 42 |
<header class="section-head">
|
| 43 |
<p class="step">00 / setup</p>
|
| 44 |
<h2 data-n-models="{N} models load when the lab starts">Models load when the lab starts</h2>
|
| 45 |
-
<p class="section-note">The first start downloads LightDec_Arthur, LightDec_V2 and Laya from Hugging Face (about
|
| 46 |
<p class="section-note" id="models-found"></p>
|
| 47 |
</header>
|
| 48 |
<div class="models" id="models">
|
|
@@ -196,6 +196,7 @@
|
|
| 196 |
<h3>The models</h3>
|
| 197 |
<p><a href="https://huggingface.co/Falconsai/LightDec_Arthur" target="_blank" rel="noopener noreferrer">LightDec_Arthur</a>: byte-level Arthur model, about 12M parameters; the code that runs it ships with DecisionLab.</p>
|
| 198 |
<p><a href="https://huggingface.co/Falconsai/LightDec_V2" target="_blank" rel="noopener noreferrer">LightDec_V2</a>: FalconDec on the Ettin-150M encoder, 2,048-token window, Apache-2.0.</p>
|
|
|
|
| 199 |
<p><a href="https://huggingface.co/convaiinnovations/laya" target="_blank" rel="noopener noreferrer">Laya</a>: by Convai Innovations, ModernBERT-large, Apache-2.0.</p>
|
| 200 |
<p>Models in the mounted <code>models</code> folder are added after these, marked "(local)": a LightDec folder has a <code>falcondec_config.json</code>, an Arthur folder a <code>config.json</code> and <code>model.safetensors</code>.</p>
|
| 201 |
<p>None of the models writes text. Each only ranks the options you give it.</p>
|
|
|
|
| 42 |
<header class="section-head">
|
| 43 |
<p class="step">00 / setup</p>
|
| 44 |
<h2 data-n-models="{N} models load when the lab starts">Models load when the lab starts</h2>
|
| 45 |
+
<p class="section-note">The first start downloads LightDec_Arthur, LightDec_V2, Enterprise Reflux Laya V2.1 and Laya from Hugging Face (about 2 GB) into the cache volume. Every LightDec (FalconDec) and Arthur model in the local <code>models</code> folder is found at start-up and loaded from there. Nothing you type leaves this server.</p>
|
| 46 |
<p class="section-note" id="models-found"></p>
|
| 47 |
</header>
|
| 48 |
<div class="models" id="models">
|
|
|
|
| 196 |
<h3>The models</h3>
|
| 197 |
<p><a href="https://huggingface.co/Falconsai/LightDec_Arthur" target="_blank" rel="noopener noreferrer">LightDec_Arthur</a>: byte-level Arthur model, about 12M parameters; the code that runs it ships with DecisionLab.</p>
|
| 198 |
<p><a href="https://huggingface.co/Falconsai/LightDec_V2" target="_blank" rel="noopener noreferrer">LightDec_V2</a>: FalconDec on the Ettin-150M encoder, 2,048-token window, Apache-2.0.</p>
|
| 199 |
+
<p><a href="https://huggingface.co/yasserrmd/enterprise-reflux-laya-v21" target="_blank" rel="noopener noreferrer">Enterprise Reflux Laya V2.1</a>: a fine-tune of Laya for ranking enterprise actions, by Mohamed Yasser; its model card marks it a research prototype, not for production.</p>
|
| 200 |
<p><a href="https://huggingface.co/convaiinnovations/laya" target="_blank" rel="noopener noreferrer">Laya</a>: by Convai Innovations, ModernBERT-large, Apache-2.0.</p>
|
| 201 |
<p>Models in the mounted <code>models</code> folder are added after these, marked "(local)": a LightDec folder has a <code>falcondec_config.json</code>, an Arthur folder a <code>config.json</code> and <code>model.safetensors</code>.</p>
|
| 202 |
<p>None of the models writes text. Each only ranks the options you give it.</p>
|
docker-compose.yml
CHANGED
|
@@ -16,6 +16,7 @@ services:
|
|
| 16 |
# The three Hub models (shown in this order, then any models in ./models, marked "(local)"):
|
| 17 |
LIGHTDEC_ARTHUR_REPO: Falconsai/LightDec_Arthur
|
| 18 |
LIGHTDEC_V2_REPO: Falconsai/LightDec_V2
|
|
|
|
| 19 |
LAYA_REPO: convaiinnovations/laya
|
| 20 |
MODELS_DIR: /models # LightDec and Arthur folders in ./models (mounted below) are added too
|
| 21 |
LIGHTDEC_VARIANT: fp16 # fp16 | int8 (compact-int8 folder), for every LightDec model
|
|
|
|
| 16 |
# The three Hub models (shown in this order, then any models in ./models, marked "(local)"):
|
| 17 |
LIGHTDEC_ARTHUR_REPO: Falconsai/LightDec_Arthur
|
| 18 |
LIGHTDEC_V2_REPO: Falconsai/LightDec_V2
|
| 19 |
+
REFLUX_LAYA_REPO: yasserrmd/enterprise-reflux-laya-v21
|
| 20 |
LAYA_REPO: convaiinnovations/laya
|
| 21 |
MODELS_DIR: /models # LightDec and Arthur folders in ./models (mounted below) are added too
|
| 22 |
LIGHTDEC_VARIANT: fp16 # fp16 | int8 (compact-int8 folder), for every LightDec model
|
tests/test_api.py
CHANGED
|
@@ -29,12 +29,15 @@ class DecideEndpointTest(unittest.TestCase):
|
|
| 29 |
from pathlib import Path
|
| 30 |
from app.registry import discover
|
| 31 |
st = self.main.status()
|
| 32 |
-
|
| 33 |
-
self.assertEqual(
|
| 34 |
-
self.assertEqual([st["models"][k]["
|
| 35 |
-
["
|
|
|
|
|
|
|
|
|
|
| 36 |
found = [folder.name for folder, _ in discover(os.environ.get("MODELS_DIR") or "/models")]
|
| 37 |
-
self.assertEqual([Path(st["models"][k]["path"]).name for k in st["order"][
|
| 38 |
|
| 39 |
def test_importing_the_app_raises_no_deprecation_warning_of_its_own(self):
|
| 40 |
import subprocess
|
|
|
|
| 29 |
from pathlib import Path
|
| 30 |
from app.registry import discover
|
| 31 |
st = self.main.status()
|
| 32 |
+
hub = ["lightdec_arthur", "lightdec_v2", "enterprise_reflux_laya_v21", "laya"]
|
| 33 |
+
self.assertEqual(st["order"][:4], hub)
|
| 34 |
+
self.assertEqual([st["models"][k]["name"] for k in hub],
|
| 35 |
+
["LightDec_Arthur", "LightDec_V2", "Enterprise Reflux Laya V2.1", "Laya"])
|
| 36 |
+
self.assertEqual([st["models"][k]["repo"] for k in hub],
|
| 37 |
+
["Falconsai/LightDec_Arthur", "Falconsai/LightDec_V2", "yasserrmd/enterprise-reflux-laya-v21",
|
| 38 |
+
"convaiinnovations/laya"])
|
| 39 |
found = [folder.name for folder, _ in discover(os.environ.get("MODELS_DIR") or "/models")]
|
| 40 |
+
self.assertEqual([Path(st["models"][k]["path"]).name for k in st["order"][4:]], found)
|
| 41 |
|
| 42 |
def test_importing_the_app_raises_no_deprecation_warning_of_its_own(self):
|
| 43 |
import subprocess
|
tests/test_links.py
CHANGED
|
@@ -26,9 +26,10 @@ class ExternalLinksTest(unittest.TestCase):
|
|
| 26 |
def test_links_the_script_builds(self):
|
| 27 |
self.check("app.js")
|
| 28 |
|
| 29 |
-
def
|
| 30 |
html = (STATIC / "index.html").read_text(encoding="utf-8")
|
| 31 |
-
for repo in ("Falconsai/LightDec_Arthur", "Falconsai/LightDec_V2", "
|
|
|
|
| 32 |
with self.subTest(repo=repo):
|
| 33 |
self.assertIn(f'href="https://huggingface.co/{repo}"', html)
|
| 34 |
self.assertNotIn("laya-v796", html)
|
|
|
|
| 26 |
def test_links_the_script_builds(self):
|
| 27 |
self.check("app.js")
|
| 28 |
|
| 29 |
+
def test_page_credits_the_hub_models(self):
|
| 30 |
html = (STATIC / "index.html").read_text(encoding="utf-8")
|
| 31 |
+
for repo in ("Falconsai/LightDec_Arthur", "Falconsai/LightDec_V2", "yasserrmd/enterprise-reflux-laya-v21",
|
| 32 |
+
"convaiinnovations/laya"):
|
| 33 |
with self.subTest(repo=repo):
|
| 34 |
self.assertIn(f'href="https://huggingface.co/{repo}"', html)
|
| 35 |
self.assertNotIn("laya-v796", html)
|
tests/test_registry.py
CHANGED
|
@@ -6,7 +6,7 @@ from pathlib import Path
|
|
| 6 |
|
| 7 |
from app.registry import load_order, model_specs, resolve_local_dir
|
| 8 |
|
| 9 |
-
HUB_KEYS = ["lightdec_arthur", "lightdec_v2", "laya"]
|
| 10 |
|
| 11 |
|
| 12 |
def folder_models(specs):
|
|
@@ -33,16 +33,17 @@ class DiscoveryTest(unittest.TestCase):
|
|
| 33 |
make_model(self.root, "LightDec_V2_Long-v1.0.0", {"name": "LightDec_V2_Long", "version": "1.0.0"})
|
| 34 |
make_model(self.root, "LightDec-v1.0.2", {"name": "LightDec", "version": "1.0.2"})
|
| 35 |
specs = model_specs(self.env)
|
| 36 |
-
self.assertEqual([s["key"] for s in specs[:
|
| 37 |
self.assertEqual([s["path"] for s in folder_models(specs)],
|
| 38 |
[str(self.root / "LightDec-v1.0.2"), str(self.root / "LightDec_V2_Long-v1.0.0")])
|
| 39 |
-
self.assertEqual(specs[
|
| 40 |
|
| 41 |
def test_names_come_from_each_config(self):
|
| 42 |
make_model(self.root, "a", {"name": "LightDec", "version": "1.0.2"})
|
| 43 |
make_model(self.root, "b", {"name": "LightDec_V2_Long", "version": "1.0.0"})
|
| 44 |
self.assertEqual([s["name"] for s in model_specs(self.env)],
|
| 45 |
-
["LightDec_Arthur", "LightDec_V2", "
|
|
|
|
| 46 |
|
| 47 |
def test_unreadable_config_falls_back_to_the_folder_name(self):
|
| 48 |
make_model(self.root, "Broken-Model", raw="{not json")
|
|
@@ -72,9 +73,9 @@ class DiscoveryTest(unittest.TestCase):
|
|
| 72 |
for i in range(6):
|
| 73 |
make_model(self.root, f"m{i}", {})
|
| 74 |
sides = [s["side"] for s in model_specs(self.env)]
|
| 75 |
-
self.assertEqual(len(sides),
|
| 76 |
-
self.assertEqual(len(set(sides)), 9)
|
| 77 |
-
self.assertEqual(sides[
|
| 78 |
|
| 79 |
def test_discovered_models_are_local_lightdec_backends(self):
|
| 80 |
make_model(self.root, "m", {})
|
|
@@ -93,13 +94,13 @@ class DiscoveryTest(unittest.TestCase):
|
|
| 93 |
self.assertEqual(str(ctx.exception), "LIGHTDEC_VARIANT must be fp16 or int8 (got 'fp8').")
|
| 94 |
|
| 95 |
def test_laya_settings(self):
|
| 96 |
-
laya = model_specs(dict(self.env, LAYA_REPO="me/laya", LAYA_FALLBACK_REPO=""))[
|
| 97 |
self.assertEqual((laya["name"], laya["repo"], laya["fallback_repo"]), ("Laya", "me/laya", ""))
|
| 98 |
-
laya = model_specs(self.env)[
|
| 99 |
self.assertEqual((laya["repo"], laya["fallback_repo"]), ("convaiinnovations/laya", ""))
|
| 100 |
|
| 101 |
def test_default_models_directory_is_slash_models(self):
|
| 102 |
-
self.assertEqual([s["key"] for s in model_specs({"MODELS_DIR": ""})][:
|
| 103 |
|
| 104 |
|
| 105 |
class LoadOrderTest(unittest.TestCase):
|
|
@@ -226,9 +227,9 @@ class ArthurDiscoveryTest(unittest.TestCase):
|
|
| 226 |
self.arthur("arthur-base")
|
| 227 |
make_model(self.root, "LightDec-v1.0.2", {"name": "LightDec", "version": "1.0.2"})
|
| 228 |
specs = model_specs(self.env)
|
| 229 |
-
self.assertEqual([(s["key"], s["kind"], s["name"]) for s in specs][
|
| 230 |
[("lightdec_v1_0_2", "lightdec", "LightDec 1.0.2 (local)"), ("arthur_base", "arthur", "Arthur base (local)")])
|
| 231 |
-
self.assertEqual(specs[
|
| 232 |
|
| 233 |
def test_pretrained_run_is_named_so(self):
|
| 234 |
self.arthur("arthur-base-pt", dict(ARTHUR_CFG, pretrain={"epochs": 1}))
|
|
@@ -249,7 +250,7 @@ class ArthurDiscoveryTest(unittest.TestCase):
|
|
| 249 |
def test_colours_continue_across_kinds(self):
|
| 250 |
self.arthur("b-arthur")
|
| 251 |
make_model(self.root, "a-lightdec", {})
|
| 252 |
-
self.assertEqual([s["side"] for s in model_specs(self.env)], ["c0", "c1", "
|
| 253 |
|
| 254 |
|
| 255 |
class HubModelsTest(unittest.TestCase):
|
|
@@ -262,14 +263,24 @@ class HubModelsTest(unittest.TestCase):
|
|
| 262 |
self.assertEqual([(s["key"], s["name"], s["repo"]) for s in self.specs],
|
| 263 |
[("lightdec_arthur", "LightDec_Arthur", "Falconsai/LightDec_Arthur"),
|
| 264 |
("lightdec_v2", "LightDec_V2", "Falconsai/LightDec_V2"),
|
|
|
|
| 265 |
("laya", "Laya", "convaiinnovations/laya")])
|
| 266 |
|
| 267 |
def test_kinds_and_sources(self):
|
| 268 |
self.assertEqual([(s["kind"], s.get("source")) for s in self.specs],
|
| 269 |
-
[("arthur", "hub"), ("lightdec", "hub"), ("laya", None)])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 270 |
|
| 271 |
def test_laya_has_no_fallback(self):
|
| 272 |
-
self.assertEqual(self.specs[
|
| 273 |
|
| 274 |
def test_hub_repos_can_be_overridden(self):
|
| 275 |
specs = model_specs({"MODELS_DIR": "/x", "LIGHTDEC_ARTHUR_REPO": "me/a", "LIGHTDEC_V2_REPO": "me/b"})
|
|
@@ -279,7 +290,7 @@ class HubModelsTest(unittest.TestCase):
|
|
| 279 |
with tempfile.TemporaryDirectory() as d:
|
| 280 |
make_model(Path(d), "LightDec_V2", {"name": "LightDec_V2_Long", "version": "1.0.0"})
|
| 281 |
specs = model_specs({"MODELS_DIR": d})
|
| 282 |
-
self.assertEqual([(s["key"], s["name"]) for s in specs][
|
| 283 |
|
| 284 |
|
| 285 |
from app.registry import warmup_enabled
|
|
|
|
| 6 |
|
| 7 |
from app.registry import load_order, model_specs, resolve_local_dir
|
| 8 |
|
| 9 |
+
HUB_KEYS = ["lightdec_arthur", "lightdec_v2", "enterprise_reflux_laya_v21", "laya"]
|
| 10 |
|
| 11 |
|
| 12 |
def folder_models(specs):
|
|
|
|
| 33 |
make_model(self.root, "LightDec_V2_Long-v1.0.0", {"name": "LightDec_V2_Long", "version": "1.0.0"})
|
| 34 |
make_model(self.root, "LightDec-v1.0.2", {"name": "LightDec", "version": "1.0.2"})
|
| 35 |
specs = model_specs(self.env)
|
| 36 |
+
self.assertEqual([s["key"] for s in specs[:4]], HUB_KEYS)
|
| 37 |
self.assertEqual([s["path"] for s in folder_models(specs)],
|
| 38 |
[str(self.root / "LightDec-v1.0.2"), str(self.root / "LightDec_V2_Long-v1.0.0")])
|
| 39 |
+
self.assertEqual(specs[3]["kind"], "laya")
|
| 40 |
|
| 41 |
def test_names_come_from_each_config(self):
|
| 42 |
make_model(self.root, "a", {"name": "LightDec", "version": "1.0.2"})
|
| 43 |
make_model(self.root, "b", {"name": "LightDec_V2_Long", "version": "1.0.0"})
|
| 44 |
self.assertEqual([s["name"] for s in model_specs(self.env)],
|
| 45 |
+
["LightDec_Arthur", "LightDec_V2", "Enterprise Reflux Laya V2.1", "Laya",
|
| 46 |
+
"LightDec 1.0.2 (local)", "LightDec_V2_Long 1.0.0 (local)"])
|
| 47 |
|
| 48 |
def test_unreadable_config_falls_back_to_the_folder_name(self):
|
| 49 |
make_model(self.root, "Broken-Model", raw="{not json")
|
|
|
|
| 73 |
for i in range(6):
|
| 74 |
make_model(self.root, f"m{i}", {})
|
| 75 |
sides = [s["side"] for s in model_specs(self.env)]
|
| 76 |
+
self.assertEqual(len(sides), 10)
|
| 77 |
+
self.assertEqual(len(set(sides)), 9) # 8 palette colours + Laya
|
| 78 |
+
self.assertEqual(sides[3], "laya")
|
| 79 |
|
| 80 |
def test_discovered_models_are_local_lightdec_backends(self):
|
| 81 |
make_model(self.root, "m", {})
|
|
|
|
| 94 |
self.assertEqual(str(ctx.exception), "LIGHTDEC_VARIANT must be fp16 or int8 (got 'fp8').")
|
| 95 |
|
| 96 |
def test_laya_settings(self):
|
| 97 |
+
laya = model_specs(dict(self.env, LAYA_REPO="me/laya", LAYA_FALLBACK_REPO=""))[3]
|
| 98 |
self.assertEqual((laya["name"], laya["repo"], laya["fallback_repo"]), ("Laya", "me/laya", ""))
|
| 99 |
+
laya = model_specs(self.env)[3]
|
| 100 |
self.assertEqual((laya["repo"], laya["fallback_repo"]), ("convaiinnovations/laya", ""))
|
| 101 |
|
| 102 |
def test_default_models_directory_is_slash_models(self):
|
| 103 |
+
self.assertEqual([s["key"] for s in model_specs({"MODELS_DIR": ""})][:4], HUB_KEYS) # empty setting falls back to /models
|
| 104 |
|
| 105 |
|
| 106 |
class LoadOrderTest(unittest.TestCase):
|
|
|
|
| 227 |
self.arthur("arthur-base")
|
| 228 |
make_model(self.root, "LightDec-v1.0.2", {"name": "LightDec", "version": "1.0.2"})
|
| 229 |
specs = model_specs(self.env)
|
| 230 |
+
self.assertEqual([(s["key"], s["kind"], s["name"]) for s in specs][4:],
|
| 231 |
[("lightdec_v1_0_2", "lightdec", "LightDec 1.0.2 (local)"), ("arthur_base", "arthur", "Arthur base (local)")])
|
| 232 |
+
self.assertEqual(specs[5]["path"], str(self.root / "arthur-base"))
|
| 233 |
|
| 234 |
def test_pretrained_run_is_named_so(self):
|
| 235 |
self.arthur("arthur-base-pt", dict(ARTHUR_CFG, pretrain={"epochs": 1}))
|
|
|
|
| 250 |
def test_colours_continue_across_kinds(self):
|
| 251 |
self.arthur("b-arthur")
|
| 252 |
make_model(self.root, "a-lightdec", {})
|
| 253 |
+
self.assertEqual([s["side"] for s in model_specs(self.env)], ["c0", "c1", "c2", "laya", "c3", "c4"])
|
| 254 |
|
| 255 |
|
| 256 |
class HubModelsTest(unittest.TestCase):
|
|
|
|
| 263 |
self.assertEqual([(s["key"], s["name"], s["repo"]) for s in self.specs],
|
| 264 |
[("lightdec_arthur", "LightDec_Arthur", "Falconsai/LightDec_Arthur"),
|
| 265 |
("lightdec_v2", "LightDec_V2", "Falconsai/LightDec_V2"),
|
| 266 |
+
("enterprise_reflux_laya_v21", "Enterprise Reflux Laya V2.1", "yasserrmd/enterprise-reflux-laya-v21"),
|
| 267 |
("laya", "Laya", "convaiinnovations/laya")])
|
| 268 |
|
| 269 |
def test_kinds_and_sources(self):
|
| 270 |
self.assertEqual([(s["kind"], s.get("source")) for s in self.specs],
|
| 271 |
+
[("arthur", "hub"), ("lightdec", "hub"), ("laya", None), ("laya", None)])
|
| 272 |
+
|
| 273 |
+
def test_reflux_is_a_laya_checkpoint_with_no_fallback_and_its_own_colour(self):
|
| 274 |
+
reflux = self.specs[2]
|
| 275 |
+
self.assertEqual((reflux["kind"], reflux["fallback_repo"]), ("laya", ""))
|
| 276 |
+
self.assertEqual(len({s["side"] for s in self.specs}), 4)
|
| 277 |
+
|
| 278 |
+
def test_reflux_repo_can_be_overridden(self):
|
| 279 |
+
specs = model_specs({"MODELS_DIR": "/x", "REFLUX_LAYA_REPO": "me/reflux"})
|
| 280 |
+
self.assertEqual(specs[2]["repo"], "me/reflux")
|
| 281 |
|
| 282 |
def test_laya_has_no_fallback(self):
|
| 283 |
+
self.assertEqual(self.specs[3]["fallback_repo"], "")
|
| 284 |
|
| 285 |
def test_hub_repos_can_be_overridden(self):
|
| 286 |
specs = model_specs({"MODELS_DIR": "/x", "LIGHTDEC_ARTHUR_REPO": "me/a", "LIGHTDEC_V2_REPO": "me/b"})
|
|
|
|
| 290 |
with tempfile.TemporaryDirectory() as d:
|
| 291 |
make_model(Path(d), "LightDec_V2", {"name": "LightDec_V2_Long", "version": "1.0.0"})
|
| 292 |
specs = model_specs({"MODELS_DIR": d})
|
| 293 |
+
self.assertEqual([(s["key"], s["name"]) for s in specs][4:], [("lightdec_v2_2", "LightDec_V2_Long 1.0.0 (local)")])
|
| 294 |
|
| 295 |
|
| 296 |
from app.registry import warmup_enabled
|