mirror of
https://github.com/Niko1221/Strata.git
synced 2026-11-07 17:38:20 -10:00
DeepSeek --parallel: the engine flag probe lives in its own module (strata_control/dsv41_flags.py), because serving must not import dsv41_engine.py (it reaches the network)
This commit is contained in:
1 parent
d8801f628c
commit
2784dfdcc4
5 files changed
+63
-42
No files matched your search
+2
-2
@@ -3435,8 +3435,8 @@ def parallel_args(cfg: dict, args: list[str]) -> list[str]:
|
||||
# experts' room; their tokens are decoded together). Not --batch: that is the Qwen engine's slots.
|
||||
# An engine package from before this flag would stop at the start on it ("unknown option"): asked of the engine itself, and said.
|
||||
try:
|
||||
from strata_control import dsv41_engine
|
||||
old_engine = dsv41_engine.takes_parallel(cfg.get("exe")) is False
|
||||
from strata_control import dsv41_flags
|
||||
old_engine = dsv41_flags.takes_parallel(cfg.get("exe")) is False
|
||||
except Exception: # noqa: BLE001 - a probe that fails decides nothing
|
||||
old_engine = False
|
||||
if old_engine:
|
||||
|
||||
@@ -1462,8 +1462,8 @@ class Runner:
|
||||
self.parallel_dropped = False
|
||||
if cfg.get("arch") != "deepseek41" or not (self.s.parallel and self.s.parallel > 1):
|
||||
return
|
||||
from strata_control import dsv41_engine
|
||||
if dsv41_engine.takes_parallel(cfg.get("exe")) is False:
|
||||
from strata_control import dsv41_flags
|
||||
if dsv41_flags.takes_parallel(cfg.get("exe")) is False:
|
||||
self.parallel_dropped = True
|
||||
text = (f"This DeepSeek engine ({Path(str(cfg.get('exe'))).parent.name or 'installed'}) is from before --parallel, so it answers one request at "
|
||||
f"a time and --parallel {self.s.parallel} is not used. Update the engine with `strata update` and start again to answer several at once.")
|
||||
|
||||
@@ -208,34 +208,6 @@ def source_reachable(source: str, timeout: float = 10.0) -> bool:
|
||||
return False
|
||||
|
||||
|
||||
_PARALLEL_SEEN: dict = {}
|
||||
|
||||
|
||||
def takes_parallel(exe: str | os.PathLike | None, timeout: float = 15.0) -> bool | None:
|
||||
"""Does this DeepSeek engine take `--parallel N` (several conversations at once)? Asked of the engine itself: its usage text (`--help`,
|
||||
which needs no card and no model) names the flag from the version that has it. True / False; None when it cannot be told (no such file,
|
||||
it would not start, no usage text came back) - then nothing is decided and the caller goes on as before. Remembered per file and time."""
|
||||
import subprocess
|
||||
try:
|
||||
path = Path(str(exe))
|
||||
key = (str(path), path.stat().st_mtime_ns, path.stat().st_size)
|
||||
except (OSError, ValueError, TypeError):
|
||||
return None
|
||||
if key in _PARALLEL_SEEN:
|
||||
return _PARALLEL_SEEN[key]
|
||||
answer: bool | None = None
|
||||
try:
|
||||
done = subprocess.run([str(path), "--help"], capture_output=True, text=True, errors="replace", timeout=timeout, cwd=str(path.parent),
|
||||
env=start_env(path), stdin=subprocess.DEVNULL)
|
||||
text = (done.stdout or "") + (done.stderr or "")
|
||||
if "--pack" in text and "--serve" in text: # its own usage text (every version prints these two)
|
||||
answer = "--parallel" in text
|
||||
except (OSError, subprocess.SubprocessError):
|
||||
answer = None
|
||||
_PARALLEL_SEEN[key] = answer
|
||||
return answer
|
||||
|
||||
|
||||
def _test_start(exe: Path, timeout: float = 120.0) -> tuple[bool, str]:
|
||||
"""The new engine starts: `strata-dsv41 --version` runs, loads its libraries and names itself (it needs no graphics card and no model).
|
||||
The package's own folders go on the library path first: a Windows HIP package carries the ROCm runtime it loads in rocm/bin."""
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
"""What a DeepSeek engine program accepts, asked of the program itself. No network and no installer code: the server may import this (strata_control/dsv41_engine.py
|
||||
reaches the network and serving must never import it)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
_SEEN: dict = {}
|
||||
|
||||
|
||||
def _env(exe: Path) -> dict:
|
||||
"""The environment of the engine's own package folders first on the library path (as dsv41_engine.start_env)."""
|
||||
env = dict(os.environ)
|
||||
try:
|
||||
from strata_control import engine_component as ec
|
||||
dirs = [d for d in ec.package_lib_dirs(exe.parent) if Path(d).is_dir()]
|
||||
except Exception: # noqa: BLE001 - the program's own folder is the fallback
|
||||
dirs = [str(exe.parent)]
|
||||
var = "PATH" if os.name == "nt" else "LD_LIBRARY_PATH"
|
||||
if dirs:
|
||||
env[var] = os.pathsep.join(dirs + ([env[var]] if env.get(var) else []))
|
||||
return env
|
||||
|
||||
|
||||
def takes_parallel(exe, timeout: float = 15.0) -> bool | None:
|
||||
"""Does this DeepSeek engine take `--parallel N` (several conversations at once)? Asked of the engine itself: its usage text (`--help`,
|
||||
which needs no card and no model) names the flag from the version that has it. True / False; None when it cannot be told (no such file,
|
||||
it would not start, no usage text came back) - then nothing is decided and the caller goes on as before. Remembered per file and time."""
|
||||
try:
|
||||
path = Path(str(exe))
|
||||
st = path.stat()
|
||||
key = (str(path), st.st_mtime_ns, st.st_size)
|
||||
except (OSError, ValueError, TypeError):
|
||||
return None
|
||||
if key in _SEEN:
|
||||
return _SEEN[key]
|
||||
answer: bool | None = None
|
||||
try:
|
||||
done = subprocess.run([str(path), "--help"], capture_output=True, text=True, errors="replace", timeout=timeout, cwd=str(path.parent),
|
||||
env=_env(path), stdin=subprocess.DEVNULL)
|
||||
text = (done.stdout or "") + (done.stderr or "")
|
||||
if "--pack" in text and "--serve" in text: # its own usage text (every version prints these two)
|
||||
answer = "--parallel" in text
|
||||
except (OSError, subprocess.SubprocessError):
|
||||
answer = None
|
||||
_SEEN[key] = answer
|
||||
return answer
|
||||
@@ -21,7 +21,7 @@ from strata_cli.launch import settings as S
|
||||
from strata_cli.launch import store
|
||||
from strata_cli.launch.catalog import Catalog
|
||||
from strata_cli.launch.runner import Runner
|
||||
from strata_control import dsv41_engine, dsv41_parallel
|
||||
from strata_control import dsv41_flags, dsv41_parallel
|
||||
from tests.terminal.launch_support import HW_12, Home, catalog, run_cli
|
||||
|
||||
R9700 = {"name": "AMD Radeon AI PRO R9700", "vram_gb": 32.0, "usable": True, "vendor": "amd", "arch": "gfx1201"}
|
||||
@@ -199,7 +199,7 @@ class TheEngineInUse(Base):
|
||||
|
||||
def test_an_engine_from_before_the_flag_is_asked_and_the_launch_goes_on_one_at_a_time(self):
|
||||
s, r = self._runner(4)
|
||||
with mock.patch.object(dsv41_engine, "takes_parallel", return_value=False):
|
||||
with mock.patch.object(dsv41_flags, "takes_parallel", return_value=False):
|
||||
r.gate_parallel(self._cfg())
|
||||
self.assertTrue(r.parallel_dropped)
|
||||
self.assertTrue(any("is from before --parallel" in n for n in r.notices), r.notices)
|
||||
@@ -208,14 +208,14 @@ class TheEngineInUse(Base):
|
||||
def test_a_current_engine_or_an_engine_that_cannot_be_asked_goes_on(self):
|
||||
for answer in (True, None):
|
||||
_s, r = self._runner(4)
|
||||
with mock.patch.object(dsv41_engine, "takes_parallel", return_value=answer):
|
||||
with mock.patch.object(dsv41_flags, "takes_parallel", return_value=answer):
|
||||
r.gate_parallel(self._cfg())
|
||||
self.assertFalse(r.parallel_dropped, answer)
|
||||
self.assertEqual(r.notices, [])
|
||||
|
||||
def test_without_the_flag_the_engine_is_not_even_asked(self):
|
||||
_s, r = self._runner(None)
|
||||
with mock.patch.object(dsv41_engine, "takes_parallel", side_effect=AssertionError("asked")):
|
||||
with mock.patch.object(dsv41_flags, "takes_parallel", side_effect=AssertionError("asked")):
|
||||
r.gate_parallel(self._cfg())
|
||||
self.assertFalse(r.parallel_dropped)
|
||||
|
||||
@@ -227,22 +227,22 @@ class TheEngineInUse(Base):
|
||||
exe.parent.mkdir()
|
||||
exe.write_text("x" * (n + 1), encoding="utf-8")
|
||||
with mock.patch("subprocess.run", return_value=mock.Mock(stdout="", stderr=text, returncode=0)) as run:
|
||||
self.assertIs(dsv41_engine.takes_parallel(exe), want, text)
|
||||
self.assertIs(dsv41_engine.takes_parallel(exe), want, text)
|
||||
self.assertIs(dsv41_flags.takes_parallel(exe), want, text)
|
||||
self.assertIs(dsv41_flags.takes_parallel(exe), want, text)
|
||||
self.assertEqual(run.call_count, 1) # asked once per file
|
||||
self.assertEqual(run.call_args[0][0], [str(exe), "--help"])
|
||||
self.assertIsNone(dsv41_engine.takes_parallel(Path(self.home.base) / "no" / "such" / "strata-dsv41"))
|
||||
self.assertIsNone(dsv41_flags.takes_parallel(Path(self.home.base) / "no" / "such" / "strata-dsv41"))
|
||||
|
||||
def test_the_server_leaves_the_flag_out_for_an_engine_from_before_it(self):
|
||||
from serve.server import parallel_args
|
||||
cfg = {"arch": "deepseek41", "exe": "/x/strata-dsv41", "parallel": 4}
|
||||
with mock.patch.object(dsv41_engine, "takes_parallel", return_value=False), contextlib.redirect_stdout(io.StringIO()) as out:
|
||||
with mock.patch.object(dsv41_flags, "takes_parallel", return_value=False), contextlib.redirect_stdout(io.StringIO()) as out:
|
||||
self.assertEqual(parallel_args(cfg, []), [])
|
||||
self.assertIn("from before --parallel", out.getvalue())
|
||||
for answer in (True, None):
|
||||
with mock.patch.object(dsv41_engine, "takes_parallel", return_value=answer):
|
||||
with mock.patch.object(dsv41_flags, "takes_parallel", return_value=answer):
|
||||
self.assertEqual(parallel_args(cfg, []), ["--parallel", "4"])
|
||||
with mock.patch.object(dsv41_engine, "takes_parallel", return_value=True), contextlib.redirect_stdout(io.StringIO()):
|
||||
with mock.patch.object(dsv41_flags, "takes_parallel", return_value=True), contextlib.redirect_stdout(io.StringIO()):
|
||||
self.assertEqual(parallel_args({**cfg, "parallel": 12}, []), ["--parallel", "8"])
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user