refactor(e2e_test): fix smg ci e2e test code quality (#16664)
This commit is contained in:
@@ -152,6 +152,7 @@ def genai_bench_runner():
|
|||||||
)
|
)
|
||||||
timeout = timeout_sec or int(os.environ.get("GENAI_BENCH_TEST_TIMEOUT", "120"))
|
timeout = timeout_sec or int(os.environ.get("GENAI_BENCH_TEST_TIMEOUT", "120"))
|
||||||
|
|
||||||
|
try:
|
||||||
proc = subprocess.Popen(
|
proc = subprocess.Popen(
|
||||||
cmd,
|
cmd,
|
||||||
env=os.environ.copy(),
|
env=os.environ.copy(),
|
||||||
@@ -159,6 +160,12 @@ def genai_bench_runner():
|
|||||||
stderr=subprocess.PIPE,
|
stderr=subprocess.PIPE,
|
||||||
text=True,
|
text=True,
|
||||||
)
|
)
|
||||||
|
except FileNotFoundError:
|
||||||
|
pytest.fail(f"genai-bench executable not found at {cli}")
|
||||||
|
except PermissionError:
|
||||||
|
pytest.fail(f"Permission denied executing {cli}")
|
||||||
|
except OSError as e:
|
||||||
|
pytest.fail(f"Failed to start genai-bench: {e}")
|
||||||
|
|
||||||
# Start GPU monitor if needed
|
# Start GPU monitor if needed
|
||||||
gpu_monitor: GPUMonitor | None = None
|
gpu_monitor: GPUMonitor | None = None
|
||||||
@@ -172,6 +179,16 @@ def genai_bench_runner():
|
|||||||
except subprocess.TimeoutExpired:
|
except subprocess.TimeoutExpired:
|
||||||
proc.kill()
|
proc.kill()
|
||||||
stdout, stderr = proc.communicate()
|
stdout, stderr = proc.communicate()
|
||||||
|
logger.error("genai-bench timed out after %ds", timeout)
|
||||||
|
|
||||||
|
# Log output if process failed or for debugging
|
||||||
|
if proc.returncode != 0:
|
||||||
|
logger.error(
|
||||||
|
"genai-bench exited with code %d\nstdout:\n%s\nstderr:\n%s",
|
||||||
|
proc.returncode,
|
||||||
|
stdout or "(empty)",
|
||||||
|
stderr or "(empty)",
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Parse and validate results
|
# Parse and validate results
|
||||||
@@ -187,6 +204,16 @@ def genai_bench_runner():
|
|||||||
gpu_monitor.log_summary()
|
gpu_monitor.log_summary()
|
||||||
gpu_monitor.assert_thresholds(thresholds)
|
gpu_monitor.assert_thresholds(thresholds)
|
||||||
|
|
||||||
|
except AssertionError:
|
||||||
|
# Log genai-bench output when results not found
|
||||||
|
logger.error(
|
||||||
|
"genai-bench output (returncode=%d):\nstdout:\n%s\nstderr:\n%s",
|
||||||
|
proc.returncode,
|
||||||
|
stdout or "(empty)",
|
||||||
|
stderr or "(empty)",
|
||||||
|
)
|
||||||
|
raise
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
_cleanup_procs(kill_procs, drain_delay_sec)
|
_cleanup_procs(kill_procs, drain_delay_sec)
|
||||||
if gpu_monitor:
|
if gpu_monitor:
|
||||||
|
|||||||
@@ -140,9 +140,9 @@ def pytest_runtest_logstart(nodeid: str, location: tuple) -> None:
|
|||||||
"""Print clear test header at start of each test."""
|
"""Print clear test header at start of each test."""
|
||||||
# Extract test name from nodeid (e.g., "test_mmlu.py::TestMMLU::test_mmlu_basic[grpc]")
|
# Extract test name from nodeid (e.g., "test_mmlu.py::TestMMLU::test_mmlu_basic[grpc]")
|
||||||
test_name = nodeid.split("::")[-1] if "::" in nodeid else nodeid
|
test_name = nodeid.split("::")[-1] if "::" in nodeid else nodeid
|
||||||
print(f"\n{'='*60}")
|
print(f"\n{'=' * LOG_SEPARATOR_WIDTH}")
|
||||||
print(f"TEST: {test_name}")
|
print(f"TEST: {test_name}")
|
||||||
print(f"{'='*60}")
|
print(f"{'=' * LOG_SEPARATOR_WIDTH}")
|
||||||
|
|
||||||
|
|
||||||
# Path setup for imports
|
# Path setup for imports
|
||||||
@@ -172,6 +172,7 @@ from infra import (
|
|||||||
ENV_SKIP_MODEL_POOL,
|
ENV_SKIP_MODEL_POOL,
|
||||||
ENV_STARTUP_TIMEOUT,
|
ENV_STARTUP_TIMEOUT,
|
||||||
LOCAL_MODES,
|
LOCAL_MODES,
|
||||||
|
LOG_SEPARATOR_WIDTH,
|
||||||
PARAM_MODEL,
|
PARAM_MODEL,
|
||||||
PARAM_SETUP_BACKEND,
|
PARAM_SETUP_BACKEND,
|
||||||
ConnectionMode,
|
ConnectionMode,
|
||||||
@@ -434,17 +435,18 @@ def pytest_collection_finish(session: pytest.Session) -> None:
|
|||||||
max_required, available_gpus = validate_gpu_requirements()
|
max_required, available_gpus = validate_gpu_requirements()
|
||||||
|
|
||||||
if max_required > available_gpus:
|
if max_required > available_gpus:
|
||||||
|
sep = "=" * LOG_SEPARATOR_WIDTH
|
||||||
raise pytest.UsageError(
|
raise pytest.UsageError(
|
||||||
f"\n{'='*60}\n"
|
f"\n{sep}\n"
|
||||||
f"GPU REQUIREMENTS EXCEEDED\n"
|
f"GPU REQUIREMENTS EXCEEDED\n"
|
||||||
f"{'='*60}\n"
|
f"{sep}\n"
|
||||||
f"Test '{_max_test_name}' requires {max_required} GPUs\n"
|
f"Test '{_max_test_name}' requires {max_required} GPUs\n"
|
||||||
f"Available: {available_gpus} GPUs\n"
|
f"Available: {available_gpus} GPUs\n"
|
||||||
f"\nOptions:\n"
|
f"\nOptions:\n"
|
||||||
f" 1. Run tests that fit: pytest -k 'not {_max_test_name.split('::')[0]}'\n"
|
f" 1. Run tests that fit: pytest -k 'not {_max_test_name.split('::')[0]}'\n"
|
||||||
f" 2. Reduce workers: @pytest.mark.workers(prefill=1, decode=1)\n"
|
f" 2. Reduce workers: @pytest.mark.workers(prefill=1, decode=1)\n"
|
||||||
f" 3. Skip GPU tests: SKIP_MODEL_POOL=1 pytest\n"
|
f" 3. Skip GPU tests: SKIP_MODEL_POOL=1 pytest\n"
|
||||||
f"{'='*60}"
|
f"{sep}"
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ from dataclasses import dataclass
|
|||||||
from typing import Dict, List, Optional
|
from typing import Dict, List, Optional
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
from infra import wait_for_health
|
||||||
|
|
||||||
from .ports import find_free_port
|
from .ports import find_free_port
|
||||||
|
|
||||||
@@ -126,22 +127,9 @@ class RouterManager:
|
|||||||
proc = subprocess.Popen(cmd)
|
proc = subprocess.Popen(cmd)
|
||||||
self._children.append(proc)
|
self._children.append(proc)
|
||||||
url = f"http://127.0.0.1:{port}"
|
url = f"http://127.0.0.1:{port}"
|
||||||
self._wait_health(url)
|
wait_for_health(url, timeout=30.0, check_interval=0.2)
|
||||||
return ProcHandle(process=proc, url=url)
|
return ProcHandle(process=proc, url=url)
|
||||||
|
|
||||||
def _wait_health(self, base_url: str, timeout: float = 30.0):
|
|
||||||
start = time.time()
|
|
||||||
with requests.Session() as s:
|
|
||||||
while time.time() - start < timeout:
|
|
||||||
try:
|
|
||||||
r = s.get(f"{base_url}/health", timeout=2)
|
|
||||||
if r.status_code == 200:
|
|
||||||
return
|
|
||||||
except requests.RequestException:
|
|
||||||
pass
|
|
||||||
time.sleep(0.2)
|
|
||||||
raise TimeoutError(f"Router at {base_url} did not become healthy")
|
|
||||||
|
|
||||||
def add_worker(self, base_url: str, worker_url: str, timeout: float = 30.0) -> None:
|
def add_worker(self, base_url: str, worker_url: str, timeout: float = 30.0) -> None:
|
||||||
r = requests.post(f"{base_url}/workers", json={"url": worker_url})
|
r = requests.post(f"{base_url}/workers", json={"url": worker_url})
|
||||||
assert (
|
assert (
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ from .constants import ( # Enums; Convenience sets; Fixture parameters; Default
|
|||||||
HEALTH_CHECK_INTERVAL,
|
HEALTH_CHECK_INTERVAL,
|
||||||
LOCAL_MODES,
|
LOCAL_MODES,
|
||||||
LOCAL_RUNTIMES,
|
LOCAL_RUNTIMES,
|
||||||
|
LOG_SEPARATOR_WIDTH,
|
||||||
|
MAX_RETRY_ATTEMPTS,
|
||||||
PARAM_BACKEND_ROUTER,
|
PARAM_BACKEND_ROUTER,
|
||||||
PARAM_MODEL,
|
PARAM_MODEL,
|
||||||
PARAM_SETUP_BACKEND,
|
PARAM_SETUP_BACKEND,
|
||||||
@@ -82,6 +84,8 @@ __all__ = [
|
|||||||
"DEFAULT_STARTUP_TIMEOUT",
|
"DEFAULT_STARTUP_TIMEOUT",
|
||||||
"DEFAULT_ROUTER_TIMEOUT",
|
"DEFAULT_ROUTER_TIMEOUT",
|
||||||
"HEALTH_CHECK_INTERVAL",
|
"HEALTH_CHECK_INTERVAL",
|
||||||
|
"MAX_RETRY_ATTEMPTS",
|
||||||
|
"LOG_SEPARATOR_WIDTH",
|
||||||
# Env vars
|
# Env vars
|
||||||
"ENV_MODELS",
|
"ENV_MODELS",
|
||||||
"ENV_BACKENDS",
|
"ENV_BACKENDS",
|
||||||
|
|||||||
@@ -58,3 +58,11 @@ DEFAULT_HOST = "127.0.0.1"
|
|||||||
DEFAULT_STARTUP_TIMEOUT = 300
|
DEFAULT_STARTUP_TIMEOUT = 300
|
||||||
DEFAULT_ROUTER_TIMEOUT = 60
|
DEFAULT_ROUTER_TIMEOUT = 60
|
||||||
HEALTH_CHECK_INTERVAL = 5
|
HEALTH_CHECK_INTERVAL = 5
|
||||||
|
|
||||||
|
# Retry configuration
|
||||||
|
MAX_RETRY_ATTEMPTS = (
|
||||||
|
6 # Max retries with exponential backoff (total ~63s: 1+2+4+8+16+32)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Display formatting
|
||||||
|
LOG_SEPARATOR_WIDTH = 60 # Width for log separator lines (e.g., "="*60)
|
||||||
|
|||||||
@@ -328,22 +328,17 @@ class Gateway:
|
|||||||
# Worker Management APIs
|
# Worker Management APIs
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
|
|
||||||
def list_workers(self, timeout: float = 5.0) -> list[WorkerInfo]:
|
def _worker_from_api_response(self, w: dict) -> WorkerInfo:
|
||||||
"""List all workers connected to the gateway.
|
"""Convert API response dict to WorkerInfo.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
w: Worker dict from API response.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List of WorkerInfo objects.
|
WorkerInfo object.
|
||||||
"""
|
"""
|
||||||
try:
|
|
||||||
resp = httpx.get(f"{self.base_url}/workers", timeout=timeout)
|
|
||||||
if resp.status_code == 200:
|
|
||||||
data = resp.json()
|
|
||||||
workers = []
|
|
||||||
for w in data.get("workers", []):
|
|
||||||
# Map API fields to WorkerInfo
|
|
||||||
status = "healthy" if w.get("is_healthy", False) else "unhealthy"
|
status = "healthy" if w.get("is_healthy", False) else "unhealthy"
|
||||||
workers.append(
|
return WorkerInfo(
|
||||||
WorkerInfo(
|
|
||||||
id=w.get("id", ""),
|
id=w.get("id", ""),
|
||||||
url=w.get("url", ""),
|
url=w.get("url", ""),
|
||||||
model=w.get("model_id"),
|
model=w.get("model_id"),
|
||||||
@@ -356,8 +351,20 @@ class Gateway:
|
|||||||
"cost": w.get("cost"),
|
"cost": w.get("cost"),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
)
|
|
||||||
return workers
|
def list_workers(self, timeout: float = 5.0) -> list[WorkerInfo]:
|
||||||
|
"""List all workers connected to the gateway.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List of WorkerInfo objects.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
resp = httpx.get(f"{self.base_url}/workers", timeout=timeout)
|
||||||
|
if resp.status_code == 200:
|
||||||
|
data = resp.json()
|
||||||
|
return [
|
||||||
|
self._worker_from_api_response(w) for w in data.get("workers", [])
|
||||||
|
]
|
||||||
return []
|
return []
|
||||||
except (httpx.RequestError, httpx.TimeoutException):
|
except (httpx.RequestError, httpx.TimeoutException):
|
||||||
return []
|
return []
|
||||||
@@ -374,21 +381,7 @@ class Gateway:
|
|||||||
try:
|
try:
|
||||||
resp = httpx.get(f"{self.base_url}/workers/{worker_id}", timeout=timeout)
|
resp = httpx.get(f"{self.base_url}/workers/{worker_id}", timeout=timeout)
|
||||||
if resp.status_code == 200:
|
if resp.status_code == 200:
|
||||||
w = resp.json()
|
return self._worker_from_api_response(resp.json())
|
||||||
status = "healthy" if w.get("is_healthy", False) else "unhealthy"
|
|
||||||
return WorkerInfo(
|
|
||||||
id=w.get("id", ""),
|
|
||||||
url=w.get("url", ""),
|
|
||||||
model=w.get("model_id"),
|
|
||||||
status=status,
|
|
||||||
pending_requests=w.get("load", 0),
|
|
||||||
metadata={
|
|
||||||
"worker_type": w.get("worker_type"),
|
|
||||||
"connection_mode": w.get("connection_mode"),
|
|
||||||
"priority": w.get("priority"),
|
|
||||||
"cost": w.get("cost"),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
return None
|
return None
|
||||||
except (httpx.RequestError, httpx.TimeoutException):
|
except (httpx.RequestError, httpx.TimeoutException):
|
||||||
return None
|
return None
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ class GPUAllocator:
|
|||||||
name = pynvml.nvmlDeviceGetName(handle)
|
name = pynvml.nvmlDeviceGetName(handle)
|
||||||
# Handle bytes vs string return type (varies by pynvml version)
|
# Handle bytes vs string return type (varies by pynvml version)
|
||||||
if isinstance(name, bytes):
|
if isinstance(name, bytes):
|
||||||
name = name.decode("utf-8")
|
name = name.decode("utf-8", errors="replace")
|
||||||
mem_info = pynvml.nvmlDeviceGetMemoryInfo(handle)
|
mem_info = pynvml.nvmlDeviceGetMemoryInfo(handle)
|
||||||
# Convert bytes to MB
|
# Convert bytes to MB
|
||||||
memory_mb = mem_info.total // (1024 * 1024)
|
memory_mb = mem_info.total // (1024 * 1024)
|
||||||
|
|||||||
@@ -305,9 +305,6 @@ class ModelPool:
|
|||||||
if ib_device:
|
if ib_device:
|
||||||
logger.info("Detected InfiniBand device: %s", ib_device)
|
logger.info("Detected InfiniBand device: %s", ib_device)
|
||||||
|
|
||||||
# Track bootstrap ports for PD groups (all PD workers of same model/mode share one)
|
|
||||||
pd_bootstrap_ports: dict[tuple[str, ConnectionMode], int] = {}
|
|
||||||
|
|
||||||
deferred: list[str] = []
|
deferred: list[str] = []
|
||||||
|
|
||||||
# Process requirements in order - all workers treated uniformly
|
# Process requirements in order - all workers treated uniformly
|
||||||
@@ -340,13 +337,8 @@ class ModelPool:
|
|||||||
deferred.append(str(identity))
|
deferred.append(str(identity))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Get bootstrap port for PD workers (shared within model/mode group)
|
# Each prefill worker needs its own bootstrap port for PD communication
|
||||||
bootstrap_port = None
|
bootstrap_port = get_open_port() if identity.is_prefill else None
|
||||||
if identity.is_prefill or identity.is_decode:
|
|
||||||
pd_key = (identity.model_id, identity.mode)
|
|
||||||
if pd_key not in pd_bootstrap_ports:
|
|
||||||
pd_bootstrap_ports[pd_key] = get_open_port()
|
|
||||||
bootstrap_port = pd_bootstrap_ports[pd_key]
|
|
||||||
|
|
||||||
# Launch the worker
|
# Launch the worker
|
||||||
self._launch_model(
|
self._launch_model(
|
||||||
@@ -354,7 +346,7 @@ class ModelPool:
|
|||||||
mode=identity.mode,
|
mode=identity.mode,
|
||||||
gpu_slot=slots[0],
|
gpu_slot=slots[0],
|
||||||
worker_type=identity.worker_type,
|
worker_type=identity.worker_type,
|
||||||
bootstrap_port=bootstrap_port if identity.is_prefill else None,
|
bootstrap_port=bootstrap_port,
|
||||||
ib_device=(
|
ib_device=(
|
||||||
ib_device if (identity.is_prefill or identity.is_decode) else None
|
ib_device if (identity.is_prefill or identity.is_decode) else None
|
||||||
),
|
),
|
||||||
@@ -888,25 +880,17 @@ class ModelPool:
|
|||||||
has_pd = any(w.is_prefill or w.is_decode for w in valid_workers)
|
has_pd = any(w.is_prefill or w.is_decode for w in valid_workers)
|
||||||
ib_device = detect_ib_device() if has_pd else None
|
ib_device = detect_ib_device() if has_pd else None
|
||||||
|
|
||||||
# Track bootstrap ports for PD groups (shared within model/mode)
|
|
||||||
pd_bootstrap_ports: dict[tuple[str, ConnectionMode], int] = {}
|
|
||||||
|
|
||||||
instances: list[ModelInstance] = []
|
instances: list[ModelInstance] = []
|
||||||
for w in valid_workers:
|
for w in valid_workers:
|
||||||
# Get bootstrap port for PD workers
|
# Each prefill worker needs its own bootstrap port for PD communication
|
||||||
bootstrap_port = None
|
bootstrap_port = get_open_port() if w.is_prefill else None
|
||||||
if w.is_prefill or w.is_decode:
|
|
||||||
pd_key = (w.model_id, w.mode)
|
|
||||||
if pd_key not in pd_bootstrap_ports:
|
|
||||||
pd_bootstrap_ports[pd_key] = get_open_port()
|
|
||||||
bootstrap_port = pd_bootstrap_ports[pd_key]
|
|
||||||
|
|
||||||
instance = self._launch_model(
|
instance = self._launch_model(
|
||||||
model_id=w.model_id,
|
model_id=w.model_id,
|
||||||
mode=w.mode,
|
mode=w.mode,
|
||||||
gpu_slot=slot_map.get(w.key),
|
gpu_slot=slot_map.get(w.key),
|
||||||
worker_type=w.worker_type,
|
worker_type=w.worker_type,
|
||||||
bootstrap_port=bootstrap_port if w.is_prefill else None,
|
bootstrap_port=bootstrap_port,
|
||||||
ib_device=ib_device if (w.is_prefill or w.is_decode) else None,
|
ib_device=ib_device if (w.is_prefill or w.is_decode) else None,
|
||||||
instance_key=w.key,
|
instance_key=w.key,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -30,12 +30,10 @@ if TYPE_CHECKING:
|
|||||||
from .simple_eval_common import Eval
|
from .simple_eval_common import Eval
|
||||||
|
|
||||||
from .simple_eval_common import ChatCompletionSampler, set_ulimit
|
from .simple_eval_common import ChatCompletionSampler, set_ulimit
|
||||||
|
from .simple_eval_mmlu import MMLU_DATASET_URL
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
# MMLU dataset URL
|
|
||||||
MMLU_DATASET_URL = "https://openaipublic.blob.core.windows.net/simple-evals/mmlu.csv"
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class EvalConfig:
|
class EvalConfig:
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ import requests
|
|||||||
from openai import OpenAI
|
from openai import OpenAI
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
|
|
||||||
|
from .constants import MAX_RETRY_ATTEMPTS
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
OPENAI_SYSTEM_MESSAGE_API = "You are a helpful assistant."
|
OPENAI_SYSTEM_MESSAGE_API = "You are a helpful assistant."
|
||||||
@@ -119,7 +121,6 @@ class ChatCompletionSampler(SamplerBase):
|
|||||||
image: str,
|
image: str,
|
||||||
encoding: str = "base64",
|
encoding: str = "base64",
|
||||||
format: str = "png",
|
format: str = "png",
|
||||||
fovea: int = 768,
|
|
||||||
):
|
):
|
||||||
new_image = {
|
new_image = {
|
||||||
"type": "image_url",
|
"type": "image_url",
|
||||||
@@ -141,7 +142,7 @@ class ChatCompletionSampler(SamplerBase):
|
|||||||
self._pack_message("system", self.system_message)
|
self._pack_message("system", self.system_message)
|
||||||
] + message_list
|
] + message_list
|
||||||
trial = 0
|
trial = 0
|
||||||
while trial < 6: # Max 63 seconds backoff (1+2+4+8+16+32)
|
while trial < MAX_RETRY_ATTEMPTS:
|
||||||
try:
|
try:
|
||||||
response = self.client.chat.completions.create(
|
response = self.client.chat.completions.create(
|
||||||
model=self.model,
|
model=self.model,
|
||||||
@@ -162,14 +163,15 @@ class ChatCompletionSampler(SamplerBase):
|
|||||||
log_fn(
|
log_fn(
|
||||||
"Request failed (retry %d/%d, backoff %ds): %s",
|
"Request failed (retry %d/%d, backoff %ds): %s",
|
||||||
trial + 1,
|
trial + 1,
|
||||||
6,
|
MAX_RETRY_ATTEMPTS,
|
||||||
exception_backoff,
|
exception_backoff,
|
||||||
e,
|
e,
|
||||||
)
|
)
|
||||||
time.sleep(exception_backoff)
|
time.sleep(exception_backoff)
|
||||||
trial += 1
|
trial += 1
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"All retry attempts exhausted after 6 retries, returning empty response"
|
"All retry attempts exhausted after %d retries, returning empty response",
|
||||||
|
MAX_RETRY_ATTEMPTS,
|
||||||
)
|
)
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ from .simple_eval_common import (
|
|||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .simple_eval_common import SamplerBase
|
from .simple_eval_common import SamplerBase
|
||||||
|
|
||||||
|
# MMLU dataset URL (hosted by OpenAI)
|
||||||
|
MMLU_DATASET_URL = "https://openaipublic.blob.core.windows.net/simple-evals/mmlu.csv"
|
||||||
|
|
||||||
SUBJECT_TO_CATEGORY = {
|
SUBJECT_TO_CATEGORY = {
|
||||||
"abstract_algebra": "stem",
|
"abstract_algebra": "stem",
|
||||||
"anatomy": "other",
|
"anatomy": "other",
|
||||||
|
|||||||
Reference in New Issue
Block a user