Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,12 @@ jobs:
run: uv sync --frozen --extra dev --extra test --extra performance

- name: Audit dependencies for known vulnerabilities
run: uv run pip-audit
# PYSEC-2026-3740 (CVE-2026-81726): nltk path traversal in model-artifact
# APIs (TransitionParser, AveragedPerceptron, PerceptronTagger, maxent).
# Unreachable here: only sent_tokenize and rouge_score's Porter stemmer
# are used. No fixed nltk release yet.
# TODO: drop the ignore - https://github.com/mlcommons/endpoints/issues/520
run: uv run pip-audit --ignore-vuln PYSEC-2026-3740

bfcl-smoke:
runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -533,5 +533,5 @@ Known failure modes when AI tools generate code for this project. Reference thes

### Dependency & Environment

- **Adding new dependencies without justification**: AI may `pip install` or add imports for packages not in `pyproject.toml`. Any new runtime, dev, or test dependency must be justified, added to the correct optional group, and pinned to an exact version (`==`). After adding a dependency, run `pip-audit` (included in `dev` extras) to verify it has no known vulnerabilities. When adding dependencies, use `uv add <package>==<version>` to update both `pyproject.toml` and `uv.lock` atomically, then run `uv run pip-audit` to check for vulnerabilities. Note: `[build-system] requires` is also pinned to exact versions for reproducibility.
- **Adding new dependencies without justification**: AI may `pip install` or add imports for packages not in `pyproject.toml`. Any new runtime, dev, or test dependency must be justified, added to the correct optional group, and pinned to an exact version (`==`). After adding a dependency, run `pip-audit` (included in `dev` extras) to verify it has no known vulnerabilities. When adding dependencies, use `uv add <package>==<version>` to update both `pyproject.toml` and `uv.lock` atomically, then run `uv run pip-audit --ignore-vuln PYSEC-2026-3740` to check for vulnerabilities (the ignored `nltk` advisory has no fixed release and its affected APIs are unused; tracked in https://github.com/mlcommons/endpoints/issues/520). Note: `[build-system] requires` is also pinned to exact versions for reproducibility.
- **Using `requests`/`aiohttp` for HTTP**: This project has its own HTTP client (`endpoint_client/http.py`) using `httptools`. AI defaults to `requests` or `aiohttp` — these should not appear in production code (test dependencies are fine).
4 changes: 3 additions & 1 deletion docs/DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,11 @@ Use `uv add <package>==<version>` to update both `pyproject.toml` and `uv.lock`
After adding a dependency, run `pip-audit` to verify it has no known vulnerabilities:

```bash
uv run pip-audit
uv run pip-audit --ignore-vuln PYSEC-2026-3740
```

`PYSEC-2026-3740` is an `nltk` advisory with no fixed release whose affected APIs this repo doesn't use; CI ignores it too. Drop the flag once [#520](https://github.com/mlcommons/endpoints/issues/520) is resolved.

## Performance Considerations

Code in `load_generator/`, `endpoint_client/worker.py`, and `async_utils/transport/` is latency-critical. In these paths:
Expand Down
16 changes: 16 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ dev = [
test = [
# Includes optional dependencies for full test coverage
"inference-endpoint[sql]",
"inference-endpoint[rouge]",
# Testing framework
"pytest==9.0.3",
"pytest-asyncio==1.3.0",
Expand All @@ -161,6 +162,21 @@ performance = [
"pytest-benchmark==5.2.3",
"memory-profiler==0.61.0",
]
rouge = [
# ROUGE text-generation scoring (eval_method: "rouge"), used by the Llama
# CNN-DailyMail / OpenOrca accuracy paths. Imported lazily in
# evaluation/scoring.py, so the base install stays lean. Resolves cleanly
# against the pinned datasets==5.0.1 - no conflicts fork needed, unlike bfcl.
# NOTE: not self-contained at runtime - nltk needs the punkt/punkt_tab
# corpora and evaluate.load("rouge") fetches its metric script from the HF
# Hub, so an offline image must prefetch both.
# nltk advisory PYSEC-2026-3740 has no fixed release and is ignored in CI's
# pip-audit (affected APIs unused); tracked in
# https://github.com/mlcommons/endpoints/issues/520
"nltk==3.10.3",
"evaluate==0.4.6",
"rouge-score==0.1.2",
]
bfcl = [
# BFCL v4 function-calling evaluation. Pins numpy==1.26.4, which is why
# the top-level numpy requirement is a lower bound (>=1.26.4).
Expand Down
16 changes: 7 additions & 9 deletions tests/integration/commands/test_benchmark_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -374,15 +374,13 @@ def _resolve_template(template_path: Path, server_url: str) -> dict:
data["settings"].setdefault("runtime", {})
data["settings"]["runtime"]["n_samples_to_issue"] = 10

# Bump the worker-init timeout for CI. The production default (60 s) is
# tight on small CI runners where Python's `spawn`-mode multiprocessing
# pays a full re-import cost per worker on top of ZMQ IPC setup; cold-
# start of the *first* parametrized template (alphabetical, so
# `concurrency_template.yaml`) consistently exceeds the budget in CI.
# The other 5 templates benefit from warm module / IPC caches and don't
# need the headroom. 120 s is a generous safety margin that does not
# change the production default, only this integration test.
data["settings"].setdefault("client", {})["worker_initialization_timeout"] = 120.0
# Raise the worker-init timeout for CI. On small runners, `spawn`-mode
# workers re-import the package, so start-up can take over 10 s.
# WorkerManager waits for readiness in slices of 10% of this timeout, and
# ready signals that straddle a slice boundary can be lost, stalling init
# until the full timeout. 300 s gives 30 s slices, longer than worker
# start-up. This does not change the production default (60 s).
data["settings"].setdefault("client", {})["worker_initialization_timeout"] = 300.0

# Accuracy datasets can't run e2e against echo server (no scorer), so keep only performance datasets.
data["datasets"] = [
Expand Down
Loading
Loading