virex-bench 0.1.2__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.
- virex_bench-0.1.2/.agents/skills/simplify/SKILL.md +75 -0
- virex_bench-0.1.2/.editorconfig +31 -0
- virex_bench-0.1.2/.gitattributes +3 -0
- virex_bench-0.1.2/.github/workflows/check_imports.py +51 -0
- virex_bench-0.1.2/.github/workflows/lint-and-test.yml +68 -0
- virex_bench-0.1.2/.github/workflows/release.yml +71 -0
- virex_bench-0.1.2/.gitignore +66 -0
- virex_bench-0.1.2/.ignore +4 -0
- virex_bench-0.1.2/.python-version +1 -0
- virex_bench-0.1.2/AGENTS.md +169 -0
- virex_bench-0.1.2/CLAUDE.md +1 -0
- virex_bench-0.1.2/LICENSE +674 -0
- virex_bench-0.1.2/PKG-INFO +197 -0
- virex_bench-0.1.2/README.md +163 -0
- virex_bench-0.1.2/docs/ENVIRONMENT_VARIABLES.md +111 -0
- virex_bench-0.1.2/docs/assets/virex_bench_logo.png +0 -0
- virex_bench-0.1.2/pyproject.toml +189 -0
- virex_bench-0.1.2/pyrightconfig.json +35 -0
- virex_bench-0.1.2/scripts/eval/run_eval_gemma_4_26b_a4b_it.sh +53 -0
- virex_bench-0.1.2/scripts/eval/run_eval_gemma_4_31b_it.sh +53 -0
- virex_bench-0.1.2/scripts/eval/run_eval_nvidia_nemotron_3_nano_30b_a3b_bf16.sh +53 -0
- virex_bench-0.1.2/scripts/eval/run_eval_nvidia_nemotron_3_nano_4b_bf16.sh +53 -0
- virex_bench-0.1.2/scripts/eval/run_eval_nvidia_nemotron_3_super_120b_a12b_fp8.sh +53 -0
- virex_bench-0.1.2/scripts/eval/run_eval_phi_4_mini_reasoning.sh +53 -0
- virex_bench-0.1.2/scripts/eval/run_eval_qwen3_5_122b_a10b_fp8.sh +53 -0
- virex_bench-0.1.2/scripts/eval/run_eval_qwen3_5_27b.sh +53 -0
- virex_bench-0.1.2/scripts/eval/run_eval_qwen3_5_35b_a3b.sh +53 -0
- virex_bench-0.1.2/scripts/eval/run_eval_qwen3_5_9b.sh +53 -0
- virex_bench-0.1.2/scripts/eval/run_eval_qwen3_6_27b.sh +53 -0
- virex_bench-0.1.2/scripts/eval/run_eval_qwen3_6_35b_a3b.sh +53 -0
- virex_bench-0.1.2/scripts/run_translate_dataset_translategemma.py +401 -0
- virex_bench-0.1.2/scripts/run_translate_dataset_translategemma.sh +26 -0
- virex_bench-0.1.2/scripts/serving/README.md +41 -0
- virex_bench-0.1.2/scripts/serving/run_sglang_gemma_4_e2b_it.sh +64 -0
- virex_bench-0.1.2/scripts/serving/run_sglang_ornith_1_0_9b.sh +43 -0
- virex_bench-0.1.2/scripts/serving/run_sglang_phi_4_mini_reasoning.sh +40 -0
- virex_bench-0.1.2/scripts/serving/run_sglang_qwen3_4b.sh +66 -0
- virex_bench-0.1.2/scripts/serving/run_sglang_qwen3_5_122b_a10b_fp8.sh +85 -0
- virex_bench-0.1.2/scripts/serving/run_sglang_qwen3_5_27b.sh +73 -0
- virex_bench-0.1.2/scripts/serving/run_sglang_qwen3_5_35b_a3b.sh +73 -0
- virex_bench-0.1.2/scripts/serving/run_sglang_qwen3_5_4b.sh +79 -0
- virex_bench-0.1.2/scripts/serving/run_sglang_qwen3_5_9b.sh +73 -0
- virex_bench-0.1.2/scripts/serving/run_sglang_qwen3_6_27b.sh +73 -0
- virex_bench-0.1.2/scripts/serving/run_sglang_qwen3_6_35b_a3b.sh +73 -0
- virex_bench-0.1.2/scripts/serving/run_sglang_qwen3_8b.sh +66 -0
- virex_bench-0.1.2/scripts/serving/run_vllm_gemma_4_12b_it.sh +51 -0
- virex_bench-0.1.2/scripts/serving/run_vllm_gemma_4_26b_a4b_it.sh +51 -0
- virex_bench-0.1.2/scripts/serving/run_vllm_gemma_4_31b_it.sh +51 -0
- virex_bench-0.1.2/scripts/serving/run_vllm_gemma_4_e2b_it.sh +49 -0
- virex_bench-0.1.2/scripts/serving/run_vllm_gemma_4_e4b_it.sh +49 -0
- virex_bench-0.1.2/scripts/serving/run_vllm_lfm2_5_8b_a1b.sh +39 -0
- virex_bench-0.1.2/scripts/serving/run_vllm_nvidia_nemotron_3_nano_30b_a3b_bf16.sh +39 -0
- virex_bench-0.1.2/scripts/serving/run_vllm_nvidia_nemotron_3_nano_4b_bf16.sh +39 -0
- virex_bench-0.1.2/scripts/serving/run_vllm_nvidia_nemotron_3_super_120b_a12b_fp8.sh +54 -0
- virex_bench-0.1.2/scripts/serving/run_vllm_ornith_1_0_9b.sh +37 -0
- virex_bench-0.1.2/scripts/serving/run_vllm_phi_4_mini_reasoning.sh +35 -0
- virex_bench-0.1.2/scripts/serving/run_vllm_qwen3_4b.sh +49 -0
- virex_bench-0.1.2/scripts/serving/run_vllm_qwen3_5_27b.sh +51 -0
- virex_bench-0.1.2/scripts/serving/run_vllm_qwen3_5_35b_a3b.sh +51 -0
- virex_bench-0.1.2/scripts/serving/run_vllm_qwen3_5_4b.sh +57 -0
- virex_bench-0.1.2/scripts/serving/run_vllm_qwen3_5_9b.sh +51 -0
- virex_bench-0.1.2/scripts/serving/run_vllm_qwen3_6_27b.sh +51 -0
- virex_bench-0.1.2/scripts/serving/run_vllm_qwen3_6_35b_a3b.sh +51 -0
- virex_bench-0.1.2/scripts/serving/run_vllm_qwen3_8b.sh +49 -0
- virex_bench-0.1.2/tests/cli/test_build_cli.py +97 -0
- virex_bench-0.1.2/tests/decoding/test_self_consistency.py +340 -0
- virex_bench-0.1.2/tests/evaluation/test_evaluate.py +535 -0
- virex_bench-0.1.2/tests/evaluation/test_judge.py +415 -0
- virex_bench-0.1.2/tests/evaluation/test_metrics.py +329 -0
- virex_bench-0.1.2/tests/models/__init__.py +0 -0
- virex_bench-0.1.2/tests/models/test_backends.py +28 -0
- virex_bench-0.1.2/tests/models/test_base.py +107 -0
- virex_bench-0.1.2/tests/strategies/cr/__init__.py +0 -0
- virex_bench-0.1.2/tests/strategies/cr/test_common.py +165 -0
- virex_bench-0.1.2/tests/strategies/cr/test_config.py +145 -0
- virex_bench-0.1.2/tests/strategies/cr/test_strategy.py +989 -0
- virex_bench-0.1.2/tests/strategies/pot/__init__.py +0 -0
- virex_bench-0.1.2/tests/strategies/pot/test_common.py +319 -0
- virex_bench-0.1.2/tests/strategies/pot/test_config.py +117 -0
- virex_bench-0.1.2/tests/strategies/pot/test_interpreter.py +635 -0
- virex_bench-0.1.2/tests/strategies/pot/test_strategy.py +634 -0
- virex_bench-0.1.2/tests/strategies/test_registry.py +161 -0
- virex_bench-0.1.2/tests/strategies/tot/test_beam_search.py +414 -0
- virex_bench-0.1.2/tests/strategies/tot/test_common.py +79 -0
- virex_bench-0.1.2/tests/strategies/tot/test_config.py +418 -0
- virex_bench-0.1.2/tests/strategies/tot/test_dfs_search.py +389 -0
- virex_bench-0.1.2/tests/strategies/tot/test_mcts_search.py +435 -0
- virex_bench-0.1.2/tests/strategies/tot/test_stats_plumbing.py +275 -0
- virex_bench-0.1.2/tests/tasks/__init__.py +0 -0
- virex_bench-0.1.2/tests/tasks/test_base.py +171 -0
- virex_bench-0.1.2/tests/test_logger.py +220 -0
- virex_bench-0.1.2/tests/test_modules.py +167 -0
- virex_bench-0.1.2/uv.lock +8149 -0
- virex_bench-0.1.2/virex_bench/__init__.py +38 -0
- virex_bench-0.1.2/virex_bench/__main__.py +4 -0
- virex_bench-0.1.2/virex_bench/cli/__init__.py +6 -0
- virex_bench-0.1.2/virex_bench/cli/build_cli.py +267 -0
- virex_bench-0.1.2/virex_bench/decoding/__init__.py +11 -0
- virex_bench-0.1.2/virex_bench/decoding/base.py +59 -0
- virex_bench-0.1.2/virex_bench/decoding/registry.py +26 -0
- virex_bench-0.1.2/virex_bench/decoding/self_consistency.py +450 -0
- virex_bench-0.1.2/virex_bench/envs.py +392 -0
- virex_bench-0.1.2/virex_bench/evaluation/__init__.py +34 -0
- virex_bench-0.1.2/virex_bench/evaluation/evaluate.py +503 -0
- virex_bench-0.1.2/virex_bench/evaluation/judge.py +482 -0
- virex_bench-0.1.2/virex_bench/evaluation/metrics.py +329 -0
- virex_bench-0.1.2/virex_bench/logger.py +132 -0
- virex_bench-0.1.2/virex_bench/models/__init__.py +27 -0
- virex_bench-0.1.2/virex_bench/models/backends.py +27 -0
- virex_bench-0.1.2/virex_bench/models/base.py +89 -0
- virex_bench-0.1.2/virex_bench/strategies/__init__.py +9 -0
- virex_bench-0.1.2/virex_bench/strategies/base.py +45 -0
- virex_bench-0.1.2/virex_bench/strategies/cot.py +30 -0
- virex_bench-0.1.2/virex_bench/strategies/cr/__init__.py +9 -0
- virex_bench-0.1.2/virex_bench/strategies/cr/common.py +255 -0
- virex_bench-0.1.2/virex_bench/strategies/cr/strategy.py +388 -0
- virex_bench-0.1.2/virex_bench/strategies/direct.py +25 -0
- virex_bench-0.1.2/virex_bench/strategies/modules.py +153 -0
- virex_bench-0.1.2/virex_bench/strategies/pot/__init__.py +9 -0
- virex_bench-0.1.2/virex_bench/strategies/pot/common.py +452 -0
- virex_bench-0.1.2/virex_bench/strategies/pot/interpreter.py +495 -0
- virex_bench-0.1.2/virex_bench/strategies/pot/strategy.py +211 -0
- virex_bench-0.1.2/virex_bench/strategies/registry.py +71 -0
- virex_bench-0.1.2/virex_bench/strategies/tot/__init__.py +9 -0
- virex_bench-0.1.2/virex_bench/strategies/tot/common.py +211 -0
- virex_bench-0.1.2/virex_bench/strategies/tot/search/__init__.py +41 -0
- virex_bench-0.1.2/virex_bench/strategies/tot/search/base.py +109 -0
- virex_bench-0.1.2/virex_bench/strategies/tot/search/beam.py +125 -0
- virex_bench-0.1.2/virex_bench/strategies/tot/search/dfs.py +191 -0
- virex_bench-0.1.2/virex_bench/strategies/tot/search/mcts.py +405 -0
- virex_bench-0.1.2/virex_bench/strategies/tot/strategy.py +234 -0
- virex_bench-0.1.2/virex_bench/tasks/__init__.py +13 -0
- virex_bench-0.1.2/virex_bench/tasks/base.py +140 -0
- virex_bench-0.1.2/virex_bench/tasks/registry.py +17 -0
- virex_bench-0.1.2/virex_bench/tasks/vietnamese_logical_reasoning.py +371 -0
- virex_bench-0.1.2/virex_bench/types/__init__.py +21 -0
- virex_bench-0.1.2/virex_bench/types/_metric.py +7 -0
- virex_bench-0.1.2/virex_bench/types/_result.py +97 -0
- virex_bench-0.1.2/virex_bench/types/_task.py +37 -0
- virex_bench-0.1.2/virex_bench/utils.py +15 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: simplify
|
|
3
|
+
description: Review changed code for reuse, quality, and efficiency, then fix any issues found.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Simplify: Code Review and Cleanup
|
|
7
|
+
|
|
8
|
+
Review all changed files for reuse, quality, and efficiency. Fix any issues found.
|
|
9
|
+
|
|
10
|
+
## Project Context
|
|
11
|
+
|
|
12
|
+
ViREx-Bench is a Vietnamese multi-step-reasoning benchmark built on **DSPy**, organized
|
|
13
|
+
around four axes — task / model / strategy / decoding — plus shared modules. See `AGENTS.md`
|
|
14
|
+
for the full layout. When reviewing and fixing, respect these boundaries:
|
|
15
|
+
|
|
16
|
+
- **Do not edit** files under `data/` (datasets managed externally) or `uv.lock` by hand.
|
|
17
|
+
- **Do not modify** generated/cached dirs: `.ruff_cache/`, `.cache/`, `_testing_results/`.
|
|
18
|
+
- **Never introduce** committed secrets or `.env` contents.
|
|
19
|
+
|
|
20
|
+
## Phase 1: Identify Changes
|
|
21
|
+
|
|
22
|
+
Run `git diff` (or `git diff HEAD` if there are staged changes) to see what changed. If there are no git changes, review the most recently modified files that the user mentioned or that you edited earlier in this conversation.
|
|
23
|
+
|
|
24
|
+
Ignore directories and files starting with `_` (e.g. `_testing_results/`, `_test_format.py`) — these are local/testing files, not part of the main codebase.
|
|
25
|
+
|
|
26
|
+
## Phase 2: Launch Three Review Agents in Parallel
|
|
27
|
+
|
|
28
|
+
Use the Agent tool to launch all three agents concurrently in a single message. Pass each agent the full diff so it has the complete context.
|
|
29
|
+
|
|
30
|
+
### Agent 1: Code Reuse Review
|
|
31
|
+
|
|
32
|
+
For each change:
|
|
33
|
+
|
|
34
|
+
1. **Search for existing utilities and helpers** (`rg`) that could replace newly written code. Common locations: `virex_bench/utils.py`, `logger.py`, per-package `common.py` (e.g. `strategies/cr/common.py`, `strategies/tot/common.py`), and files adjacent to the changed ones.
|
|
35
|
+
2. **Flag any new function that duplicates existing functionality.** Suggest the existing function to use instead — e.g. reimplementing `premises_to_text`, ad-hoc logger setup instead of `init_logger`, or a new registry lookup that duplicates `get_task` / `get_strategy` / `get_decoding`.
|
|
36
|
+
3. **Flag any inline logic that could use an existing utility** — hand-rolled string manipulation, manual `os.path` handling, direct `os.environ` reads that should go through `virex_bench/envs.py`, and similar patterns are common candidates.
|
|
37
|
+
|
|
38
|
+
### Agent 2: Code Quality Review
|
|
39
|
+
|
|
40
|
+
Review the same changes for hacky patterns:
|
|
41
|
+
|
|
42
|
+
1. **Redundant state**: state that duplicates existing state, cached values that could be derived
|
|
43
|
+
2. **Parameter sprawl**: adding new parameters to a function instead of generalizing or restructuring existing ones; small helper methods that are referenced only once (inline them)
|
|
44
|
+
3. **Copy-paste with slight variation**: near-duplicate code blocks that should be unified with a shared abstraction
|
|
45
|
+
4. **Leaky abstractions**: exposing internal details that should be encapsulated, or breaking existing abstraction boundaries (e.g. bypassing the task/model/strategy/decoding registries, or reaching into a `dspy.Module`'s internals)
|
|
46
|
+
5. **Stringly-typed code**: raw strings/dicts where a `pydantic.BaseModel`, enum, or string-union already exists; `dataclasses` where the codebase uses `pydantic.BaseModel`
|
|
47
|
+
6. **Style mismatches**: truthy/falsy checks (`if x`) where `is None` / `is not None` is required for valid falsy values; `pathlib.Path` where the codebase uses `str` + `os.path`; short/abbreviated names (`ri`, `ip`, `el`) where verbose self-documenting names are the convention; `%`-style logging instead of f-strings; `print()` for diagnostics instead of the shared logger; `type[T]` misuse (passing an instance where a class is expected, e.g. `signature: type[dspy.Signature]`)
|
|
48
|
+
7. **DSPy convention drift**: new strategies that aren't `dspy.Module` subclasses or don't follow the existing signature/module patterns in `strategies/`; signature docstrings or field descriptions written in a language other than **English** (task data stays native, but the instruction contract is English)
|
|
49
|
+
8. **Unnecessary or over-verbose comments**: comments explaining WHAT the code does (well-named identifiers already do that), narrating the change, or referencing the task/caller — delete these; keep only non-obvious WHY (hidden constraints, subtle invariants, workarounds). For comments worth keeping, trim multi-line/rambling explanations down to a single concise line.
|
|
50
|
+
|
|
51
|
+
### Agent 3: Efficiency Review
|
|
52
|
+
|
|
53
|
+
Review the same changes for efficiency:
|
|
54
|
+
|
|
55
|
+
1. **Unnecessary work**: redundant computations, repeated file reads, duplicate LM/API calls, N+1 patterns
|
|
56
|
+
2. **Missed concurrency**: independent operations run sequentially when they could run in parallel (e.g. per-example LM calls, independent propose/evaluate steps in ToT/CR)
|
|
57
|
+
3. **Hot-path bloat**: new blocking work added to the per-example evaluation loop or per-LM-call path
|
|
58
|
+
4. **Unnecessary existence checks**: pre-checking file/resource existence before operating (TOCTOU anti-pattern) — operate directly and handle the error
|
|
59
|
+
5. **Memory**: unbounded data structures, missing cleanup (e.g. accumulating full LM transcripts across a large eval run)
|
|
60
|
+
6. **Overly broad operations**: reading entire files/datasets when only a portion is needed, loading all items when filtering for one
|
|
61
|
+
|
|
62
|
+
## Phase 3: Fix Issues
|
|
63
|
+
|
|
64
|
+
Wait for all three agents to complete. Aggregate their findings and fix each issue directly. If a finding is a false positive or not worth addressing, note it and move on — do not argue with the finding, just skip it.
|
|
65
|
+
|
|
66
|
+
After fixing, confirm the changed files still pass the project's checks:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
uv run --no-sync ruff check path/to/file.py
|
|
70
|
+
uv run --no-sync ruff format path/to/file.py
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Pyright runs in strict mode — do not introduce type errors, and only suppress with `# pyright: ignore` for genuine false positives, never to silence a legitimate error. If the change touches behavior, also run the relevant tests (`uv run --no-sync pytest tests/...`, which mirror the package layout).
|
|
74
|
+
|
|
75
|
+
When done, briefly summarize what was fixed (or confirm the code was already clean).
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# https://editorconfig.org/
|
|
2
|
+
|
|
3
|
+
root = true
|
|
4
|
+
|
|
5
|
+
[*]
|
|
6
|
+
indent_style = space
|
|
7
|
+
indent_size = 4
|
|
8
|
+
|
|
9
|
+
end_of_line = lf
|
|
10
|
+
charset = utf-8
|
|
11
|
+
trim_trailing_whitespace = true
|
|
12
|
+
insert_final_newline = true
|
|
13
|
+
|
|
14
|
+
[*.md]
|
|
15
|
+
trim_trailing_whitespace = false
|
|
16
|
+
|
|
17
|
+
[*.py]
|
|
18
|
+
max_line_length = 100
|
|
19
|
+
|
|
20
|
+
[*.sh]
|
|
21
|
+
indent_size = 2
|
|
22
|
+
|
|
23
|
+
[*.{json,yaml,yml}]
|
|
24
|
+
indent_size = 2
|
|
25
|
+
|
|
26
|
+
[{Makefile,makefile}]
|
|
27
|
+
indent_style = tab
|
|
28
|
+
indent_size = 2
|
|
29
|
+
|
|
30
|
+
[*.txt]
|
|
31
|
+
insert_final_newline = false
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import importlib.util
|
|
5
|
+
import pathlib
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def check_imports(args: argparse.Namespace) -> None:
|
|
10
|
+
src_path = pathlib.Path(args.src_path)
|
|
11
|
+
num_files = 0
|
|
12
|
+
for pyfile in src_path.rglob("*.py"):
|
|
13
|
+
print("Trying to import", pyfile)
|
|
14
|
+
module_name = pyfile.with_suffix("").as_posix().replace("/", ".")
|
|
15
|
+
spec = importlib.util.spec_from_file_location(
|
|
16
|
+
name=module_name,
|
|
17
|
+
location=pyfile,
|
|
18
|
+
)
|
|
19
|
+
if spec is None:
|
|
20
|
+
print(f"Failed to load {pyfile}", file=sys.stderr)
|
|
21
|
+
raise SystemExit(1)
|
|
22
|
+
|
|
23
|
+
assert spec.loader is not None
|
|
24
|
+
module = importlib.util.module_from_spec(spec)
|
|
25
|
+
try:
|
|
26
|
+
spec.loader.exec_module(module)
|
|
27
|
+
num_files += 1
|
|
28
|
+
except Exception as err:
|
|
29
|
+
print(f"Error importing {module_name}: {err}", file=sys.stderr)
|
|
30
|
+
raise SystemExit(1) from err
|
|
31
|
+
|
|
32
|
+
print(f"All {num_files} imports checked successfully.")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def main() -> None:
|
|
36
|
+
parser = argparse.ArgumentParser(
|
|
37
|
+
description="Check imports in Python files",
|
|
38
|
+
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
|
39
|
+
)
|
|
40
|
+
parser.add_argument(
|
|
41
|
+
"--src_path",
|
|
42
|
+
type=str,
|
|
43
|
+
help="Path to the source directory",
|
|
44
|
+
default="src",
|
|
45
|
+
)
|
|
46
|
+
args = parser.parse_args()
|
|
47
|
+
check_imports(args)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
if __name__ == "__main__":
|
|
51
|
+
main()
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
name: Lint and Test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, dev]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main, dev]
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
check-imports:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
strategy:
|
|
14
|
+
matrix:
|
|
15
|
+
python-version: ["3.12"]
|
|
16
|
+
steps:
|
|
17
|
+
- name: Clone the repository
|
|
18
|
+
uses: actions/checkout@v7
|
|
19
|
+
- name: Install the latest version of uv and set the python version
|
|
20
|
+
uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0
|
|
21
|
+
with:
|
|
22
|
+
version: ">=0.9.21"
|
|
23
|
+
python-version: ${{ matrix.python-version }}
|
|
24
|
+
enable-cache: true
|
|
25
|
+
- name: Check imports
|
|
26
|
+
run: |
|
|
27
|
+
export PYTHONPATH="${{ github.workspace }}"
|
|
28
|
+
uv run --frozen python .github/workflows/check_imports.py --src_path virex_bench
|
|
29
|
+
|
|
30
|
+
lint-with-ruff:
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
steps:
|
|
33
|
+
- name: Clone the repository
|
|
34
|
+
uses: actions/checkout@v7
|
|
35
|
+
|
|
36
|
+
- name: Install the latest version of uv and set the python version
|
|
37
|
+
uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0
|
|
38
|
+
with:
|
|
39
|
+
version: ">=0.9.21"
|
|
40
|
+
enable-cache: true
|
|
41
|
+
|
|
42
|
+
- name: Lint with ruff
|
|
43
|
+
run: |
|
|
44
|
+
uv run --frozen ruff check --output-format=github virex_bench tests scripts
|
|
45
|
+
|
|
46
|
+
- name: Check formatting with ruff
|
|
47
|
+
run: |
|
|
48
|
+
uv run --frozen ruff format --check --output-format=github virex_bench tests scripts
|
|
49
|
+
|
|
50
|
+
test-with-pytest:
|
|
51
|
+
runs-on: ubuntu-latest
|
|
52
|
+
strategy:
|
|
53
|
+
matrix:
|
|
54
|
+
python-version: ["3.12", "3.13", "3.14"]
|
|
55
|
+
steps:
|
|
56
|
+
- name: Clone the repository
|
|
57
|
+
uses: actions/checkout@v7
|
|
58
|
+
|
|
59
|
+
- name: Install the latest version of uv and set the python version
|
|
60
|
+
uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0
|
|
61
|
+
with:
|
|
62
|
+
version: ">=0.9.21"
|
|
63
|
+
python-version: ${{ matrix.python-version }}
|
|
64
|
+
enable-cache: true
|
|
65
|
+
|
|
66
|
+
- name: Run tests with pytest
|
|
67
|
+
run: |
|
|
68
|
+
uv run --frozen pytest tests -v
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
permissions: {}
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
build:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- name: Clone the repository
|
|
14
|
+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
15
|
+
with:
|
|
16
|
+
# hatch-vcs derives the version from git tags, so full history is required.
|
|
17
|
+
fetch-depth: 0
|
|
18
|
+
|
|
19
|
+
- name: Install the latest version of uv
|
|
20
|
+
uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0
|
|
21
|
+
with:
|
|
22
|
+
version: ">=0.9.21"
|
|
23
|
+
enable-cache: true
|
|
24
|
+
|
|
25
|
+
- name: Build sdist and wheel
|
|
26
|
+
run: uv build
|
|
27
|
+
|
|
28
|
+
- name: Check distribution metadata
|
|
29
|
+
run: uvx twine check dist/*
|
|
30
|
+
|
|
31
|
+
- name: Upload distribution artifacts
|
|
32
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
33
|
+
with:
|
|
34
|
+
name: dist
|
|
35
|
+
path: dist/
|
|
36
|
+
|
|
37
|
+
publish-testpypi:
|
|
38
|
+
needs: build
|
|
39
|
+
if: github.event.release.prerelease == true
|
|
40
|
+
runs-on: ubuntu-latest
|
|
41
|
+
environment: testpypi
|
|
42
|
+
permissions:
|
|
43
|
+
id-token: write
|
|
44
|
+
steps:
|
|
45
|
+
- name: Download distribution artifacts
|
|
46
|
+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
47
|
+
with:
|
|
48
|
+
name: dist
|
|
49
|
+
path: dist/
|
|
50
|
+
|
|
51
|
+
- name: Publish to TestPyPI
|
|
52
|
+
uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0
|
|
53
|
+
with:
|
|
54
|
+
repository-url: https://test.pypi.org/legacy/
|
|
55
|
+
|
|
56
|
+
publish-pypi:
|
|
57
|
+
needs: build
|
|
58
|
+
if: github.event.release.prerelease == false
|
|
59
|
+
runs-on: ubuntu-latest
|
|
60
|
+
environment: pypi
|
|
61
|
+
permissions:
|
|
62
|
+
id-token: write
|
|
63
|
+
steps:
|
|
64
|
+
- name: Download distribution artifacts
|
|
65
|
+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
66
|
+
with:
|
|
67
|
+
name: dist
|
|
68
|
+
path: dist/
|
|
69
|
+
|
|
70
|
+
- name: Publish to PyPI
|
|
71
|
+
uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# python stuff
|
|
2
|
+
__pycache__
|
|
3
|
+
.ipynb_checkpoints
|
|
4
|
+
|
|
5
|
+
# virtual environments
|
|
6
|
+
.venv
|
|
7
|
+
.venv.*
|
|
8
|
+
.venv-*
|
|
9
|
+
|
|
10
|
+
# env
|
|
11
|
+
.env
|
|
12
|
+
.env.*
|
|
13
|
+
|
|
14
|
+
# unit test / coverage reports
|
|
15
|
+
htmlcov/
|
|
16
|
+
.tox/
|
|
17
|
+
.nox/
|
|
18
|
+
.coverage
|
|
19
|
+
.coverage.*
|
|
20
|
+
.cache
|
|
21
|
+
.tmp/
|
|
22
|
+
nosetests.xml
|
|
23
|
+
coverage.xml
|
|
24
|
+
*.cover
|
|
25
|
+
*.py,cover
|
|
26
|
+
.hypothesis/
|
|
27
|
+
.pytest_cache/
|
|
28
|
+
cover/
|
|
29
|
+
|
|
30
|
+
# local stuff
|
|
31
|
+
_*
|
|
32
|
+
!__*__.py
|
|
33
|
+
!/virex_bench/types/_*
|
|
34
|
+
/checkpoints
|
|
35
|
+
*.local
|
|
36
|
+
# /.plans
|
|
37
|
+
/.code-review
|
|
38
|
+
/results
|
|
39
|
+
/slides
|
|
40
|
+
/notebooks
|
|
41
|
+
/tmp/
|
|
42
|
+
/report/
|
|
43
|
+
/.bashrc
|
|
44
|
+
/final_results/
|
|
45
|
+
|
|
46
|
+
# datasets
|
|
47
|
+
/data
|
|
48
|
+
|
|
49
|
+
# log files
|
|
50
|
+
*.log
|
|
51
|
+
*.logs
|
|
52
|
+
|
|
53
|
+
# cache
|
|
54
|
+
.pytest_cache
|
|
55
|
+
.ruff_cache
|
|
56
|
+
|
|
57
|
+
# shell scripts
|
|
58
|
+
s.sh
|
|
59
|
+
|
|
60
|
+
# other
|
|
61
|
+
*.bak
|
|
62
|
+
*.backup
|
|
63
|
+
/*.pdf
|
|
64
|
+
/*.json
|
|
65
|
+
!/pyrightconfig.json
|
|
66
|
+
/refs
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
## Project
|
|
4
|
+
|
|
5
|
+
**ViREx-Bench** (Vietnamese Reasoning Exploration Benchmark) is a lightweight framework
|
|
6
|
+
for exploring **multi-step reasoning of LLMs for Vietnamese**.
|
|
7
|
+
|
|
8
|
+
The project has two expected outputs:
|
|
9
|
+
|
|
10
|
+
1. **A Vietnamese logical-reasoning dataset** — each row contains a set of *premises* and a
|
|
11
|
+
*question* (with a gold answer), framing logical-reasoning problems in Vietnamese.
|
|
12
|
+
2. **An evaluation framework** that measures how much each inference-time reasoning strategy
|
|
13
|
+
improves over a direct-answer baseline on that dataset.
|
|
14
|
+
|
|
15
|
+
The framework targets two orthogonal research axes (planned scope listed; see each
|
|
16
|
+
registry for what is currently implemented):
|
|
17
|
+
|
|
18
|
+
- **Prompting / inference-time scaling** (`strategies/`): Chain-of-Thought (CoT),
|
|
19
|
+
Tree-of-Thought (ToT) with pluggable search (beam, DFS, MCTS), Cumulative Reasoning
|
|
20
|
+
(CR), Self-Consistency, and Program-of-Thought with symbolic reasoning (Z3 solver).
|
|
21
|
+
*Implemented: direct baseline, CoT, CR, ToT (beam + DFS + MCTS search).*
|
|
22
|
+
- **Decoding** (`decoding/`): the baseline (single candidate, or multiple candidates
|
|
23
|
+
aggregated by majority vote), Best-of-N with a verifier, and speculative decoding to
|
|
24
|
+
speed up inference. *Implemented: single-pass baseline, self-consistency (N-sample
|
|
25
|
+
majority vote + LLM aggregation).*
|
|
26
|
+
|
|
27
|
+
**DSPy** is the main framework for implementing reasoning strategies. The CLI design is
|
|
28
|
+
modeled on [`mteb`](https://github.com/embeddings-benchmark/mteb) — a CLI is sufficient
|
|
29
|
+
(no web/leaderboard UI or serving layer).
|
|
30
|
+
|
|
31
|
+
## Commands
|
|
32
|
+
|
|
33
|
+
Always prefix Python/tool commands with `uv run --no-sync`, omit the `--no-sync` flag only when you actually needed to avoid syncing packages everytime (which take times).
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Lint
|
|
37
|
+
uv run --no-sync ruff check
|
|
38
|
+
|
|
39
|
+
# Format
|
|
40
|
+
uv run --no-sync ruff format
|
|
41
|
+
|
|
42
|
+
# Run the benchmark CLI (task × model × strategy × decoding)
|
|
43
|
+
# Models are served behind an OpenAI-compatible endpoint (no local loading).
|
|
44
|
+
uv run virex-bench run \
|
|
45
|
+
--model Qwen/Qwen3.5 \
|
|
46
|
+
--task vietnamese-logical-reasoning \
|
|
47
|
+
--strategy cot \
|
|
48
|
+
--backend openai \
|
|
49
|
+
--api-base http://localhost:8000/v1 \
|
|
50
|
+
--output-dir results
|
|
51
|
+
|
|
52
|
+
# `vb` is a shorter alias for `virex-bench`
|
|
53
|
+
uv run vb run --model Qwen/Qwen3.5 --strategy cot
|
|
54
|
+
|
|
55
|
+
# Inspect available tasks / strategies
|
|
56
|
+
uv run virex-bench tasks --list
|
|
57
|
+
uv run virex-bench strategies --list
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### File-scoped fast feedback
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
uv run --no-sync ruff check path/to/file.py
|
|
64
|
+
uv run --no-sync ruff format path/to/file.py
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Project Structure
|
|
68
|
+
|
|
69
|
+
The package is organized around four axes — **task** (dataset), **model** (backend),
|
|
70
|
+
**strategy** (prompting), and **decoding** (aggregation) — wired together by the
|
|
71
|
+
evaluation orchestrator. Layout is inspired by `mteb` (task × model registries + a thin
|
|
72
|
+
CLI), with two extra axes for reasoning and decoding.
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
virex_bench/
|
|
76
|
+
├── cli/ # argparse CLI: `virex-bench run | tasks | strategies`
|
|
77
|
+
│ └── build_cli.py # build_parser / main + subcommand handlers
|
|
78
|
+
├── envs.py # centralized, lazily-read environment variables (vLLM-style)
|
|
79
|
+
├── logger.py # init_logger(__name__) — shared logging setup
|
|
80
|
+
├── utils.py # shared helpers (premises_to_text — numbered premise block)
|
|
81
|
+
├── types/ # pydantic data models + type aliases (mirrors mteb/types)
|
|
82
|
+
│ ├── __init__.py # re-exports all public types
|
|
83
|
+
│ ├── _task.py # ReasoningExample, DatasetConfig, TaskMetadata
|
|
84
|
+
│ ├── _result.py # TaskResult, EvaluationReport, JudgeOutcome
|
|
85
|
+
│ └── _metric.py # ReasoningMetric callable alias
|
|
86
|
+
├── tasks/ # reasoning datasets + registry
|
|
87
|
+
│ ├── base.py # ReasoningTask base class
|
|
88
|
+
│ ├── registry.py # get_task / list_tasks
|
|
89
|
+
│ └── vietnamese_logical_reasoning.py
|
|
90
|
+
├── models/ # LM layer — OpenAI-compatible endpoints via dspy.LM
|
|
91
|
+
│ ├── __init__.py # get_model
|
|
92
|
+
│ ├── base.py # BaseLM(dspy.LM) wrapper
|
|
93
|
+
│ └── backends.py # load_backend: build a BaseLM for an OpenAI-compatible endpoint
|
|
94
|
+
├── strategies/ # PROMPTING / inference-time scaling (dspy.Module subclasses)
|
|
95
|
+
│ ├── base.py # ReasoningStrategy base class (+ accepts_variant flag)
|
|
96
|
+
│ ├── registry.py # get_strategy / list_strategies + composite-name parsing (direct, cot, cr, tot[-beam|-dfs|-mcts])
|
|
97
|
+
│ ├── direct.py # baseline: direct answer
|
|
98
|
+
│ ├── cot.py # Chain-of-Thought
|
|
99
|
+
│ ├── modules.py # reusable dspy modules: ChainOfThought, DualTask2ChainOfThought, ThinkingCaptureLM
|
|
100
|
+
│ ├── cr/ # Cumulative Reasoning strategy package (Zhang et al., 2023)
|
|
101
|
+
│ │ ├── strategy.py # CRStrategy — propose/verify accumulation loop + solver
|
|
102
|
+
│ │ └── common.py # shared signatures + helpers (proposer/verifiers, CRConfig, verdict buckets)
|
|
103
|
+
│ └── tot/ # Tree-of-Thoughts strategy package (Yao et al., 2023)
|
|
104
|
+
│ ├── strategy.py # ToTStrategy — propose/evaluate/aggregate over a thought tree
|
|
105
|
+
│ ├── common.py # shared signatures + helpers (proposer/evaluator, scoring, dedupe)
|
|
106
|
+
│ └── search/ # pluggable search algorithms (beam, DFS, MCTS)
|
|
107
|
+
│ ├── __init__.py # search registry: build_search / list_search
|
|
108
|
+
│ ├── base.py # SearchConfig, SearchResult, ThoughtSearch ABC
|
|
109
|
+
│ ├── beam.py # BeamSearch (ToT's BFS)
|
|
110
|
+
│ ├── dfs.py # DFSSearch (backtracking + value pruning)
|
|
111
|
+
│ └── mcts.py # MCTSSearch (Monte-Carlo Tree Search)
|
|
112
|
+
├── decoding/ # DECODING / answer aggregation
|
|
113
|
+
│ ├── base.py # DecodingStrategy base + SinglePass (single-candidate baseline)
|
|
114
|
+
│ ├── registry.py # get_decoding / list_decoding
|
|
115
|
+
│ └── self_consistency.py # SelfConsistency: N-sample majority vote + LLM aggregation
|
|
116
|
+
├── evaluation/ # orchestration + scoring + LLM-as-a-judge
|
|
117
|
+
│ ├── evaluate.py # task × model × strategy loop + report serialization (save_report)
|
|
118
|
+
│ ├── metrics.py # accuracy metrics + METRIC_REGISTRY / get_metric / judge_example
|
|
119
|
+
│ └── judge.py # LLMJudge base, LogicalReasoningJudge, JUDGE_REGISTRY / build_judge
|
|
120
|
+
└── __main__.py # `python -m virex_bench` entry point -> cli.main
|
|
121
|
+
|
|
122
|
+
data/ # datasets (managed externally — do not edit by hand)
|
|
123
|
+
notebooks/ # dataset-prep notebooks (e.g. eval-round → HF dataset conversion)
|
|
124
|
+
scripts/ # dataset translation helpers + model-serving launchers (serving/)
|
|
125
|
+
tests/ # pytest suite — mirrors the package layout (cli / evaluation / strategies [+ cr, tot])
|
|
126
|
+
results/ # benchmark run outputs
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Development and Code Style
|
|
130
|
+
|
|
131
|
+
### Development Guide
|
|
132
|
+
|
|
133
|
+
- **Python 3.12** — use modern syntax (`str | None`, `list[int]`, etc.)
|
|
134
|
+
- **Git**: Do not try to use `git checkout <file>` to discard or revert changes as you might cause loose uncommitted work.
|
|
135
|
+
- **Formatter**: Ruff (`uv run --no-sync ruff format`) — double quotes, 4-space indent, LF endings, line length 99
|
|
136
|
+
- **Linter**: Ruff (`uv run --no-sync ruff check`) — rules: B, C, E, F, I, W, RUF013, UP006
|
|
137
|
+
- **Type checker**: Pyright in strict mode. Use `# pyright: ignore` to suppress false positive or workaround some limitation in the type checker. DO NOT silence legitimate type errors.
|
|
138
|
+
- **Testing**: pytest (`uv run --no-sync pytest`)
|
|
139
|
+
- **Imports**: sorted by Ruff (isort rules), grouped: stdlib → third-party → local
|
|
140
|
+
- **DSPy**: Reasoning strategies are implemented as `dspy.Module` subclasses under `strategies/`. Follow the existing patterns there for signatures and modules. Write signature docstrings and field descriptions in **English** (the instruction language), even for Vietnamese tasks — the target models are multilingual, and English instructions keep the prompt contract consistent across tasks. The task data (premises/questions/answers) stays in its native language.
|
|
141
|
+
- **Grepping**: Prefer using `rg` (ripgrep) over `grep` for speed and better defaults.
|
|
142
|
+
|
|
143
|
+
### Code Style
|
|
144
|
+
|
|
145
|
+
- **Pydantic**: Use `pydantic.BaseModel` for data models (examples, configs, results, reports) — not `dataclasses`. Serialize with `model_dump()` / `model_dump_json()`.
|
|
146
|
+
- **Logging**: Use the shared logger — `from virex_bench.logger import init_logger` then `logger = init_logger(__name__)` at module top. Prefer f-strings in logging calls over `%`-style logger formatting. Do not call `print()` for diagnostics or configure `logging` directly (CLI user-facing output via `print` is fine).
|
|
147
|
+
- **Env vars**: All environment variables go through `virex_bench/envs.py` — never read `os.environ` directly elsewhere. Add a typed declaration in the `TYPE_CHECKING` block and a lazy `lambda` entry in `environment_variables`, then access via `from virex_bench import envs` / `envs.VAR_NAME`. Access is lazy (read at use time, not import time), so set vars before first access.
|
|
148
|
+
- **CLI**: `argparse`-based subcommands (`run`, `tasks`, `strategies`), modeled on `mteb`. Both `virex-bench` and the short alias `vb` map to `cli:main`. Keep command handlers thin — delegate to `evaluation/`, `tasks/`, `models/`.
|
|
149
|
+
- **File path:** Use raw `str` for file paths and `os.path` for path manipulations. Avoid `pathlib.Path` to keep things simple and consistent across the codebase.
|
|
150
|
+
- **Variable names:** Use verbose, self-documenting names. Avoid short abbreviations (e.g., `ri`, `ip`, `ua`, `ui`, `el`, `t`) — prefer `request_metadata`, `client_ip`, `client_user_agent`, `elapsed`, etc. Single-letter names are only acceptable as loop indices or in very narrow local scopes (e.g., list comprehensions).
|
|
151
|
+
- **None check:** Use `if x is None` and `if x is not None` for checking if a variable is `None`. Avoid truthy/falsy checks like `if x` or `if not x` when the variable can have valid falsy values (e.g., empty string, zero, empty list).
|
|
152
|
+
- **`type[T]` hints:** Use `type[T]` when a function/field expects a *class* (to instantiate or inspect later), not an instance — e.g. `signature: type[dspy.Signature]` and registries like `dict[str, type[ReasoningStrategy]]`. Pass the class itself (`DirectStrategy`), not an instance (`DirectStrategy()`).
|
|
153
|
+
- **Comments:** Do not add decorative separator/banner comments — no `# --- text ---`, `# =====`, or full-line `# ---------` dividers between sections. If a section genuinely needs a title, use a plain `# Title` comment (no surrounding dashes/equal signs); otherwise rely on PEP 8's two blank lines between top-level definitions. Only add comments to explain non-obvious logic — never to delimit regions.
|
|
154
|
+
- Do not create small helper methods that are referenced only once.
|
|
155
|
+
|
|
156
|
+
## Code review
|
|
157
|
+
|
|
158
|
+
When asked for reviewing changes, focus on:
|
|
159
|
+
- Potential bugs introduced by the change
|
|
160
|
+
- Check for behavior mismatches for refactoring changes
|
|
161
|
+
- Code quality and readability (style, structure, naming, etc should match the existing codebase and be clear)
|
|
162
|
+
- Ignore directories and files starting with `_` (e.g., `_testing_results/`, `_test_format.py`) as they are testing or local files and not part of the main codebase.
|
|
163
|
+
|
|
164
|
+
## Boundaries
|
|
165
|
+
|
|
166
|
+
- **Never commit** `.env` files or API keys/secrets
|
|
167
|
+
- **Do not edit** files under `data/` directly — datasets are managed externally
|
|
168
|
+
- **Do not modify** generated/cached directories: `.ruff_cache/`, `.cache/`, `_testing_results/`
|
|
169
|
+
- **Do not touch** `uv.lock` by hand
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
AGENTS.md
|