rudhratej09 commited on
Commit
c334c8e
·
verified ·
1 Parent(s): ee3dd3b

Update server/tasks.py

Browse files
Files changed (1) hide show
  1. server/tasks.py +129 -85
server/tasks.py CHANGED
@@ -1,87 +1,131 @@
1
- """Task definitions and router for the validator server."""
2
 
3
  from __future__ import annotations
4
- from typing import Callable, Optional, Any, Dict
5
- import sys
6
-
7
- def _get_server_app():
8
- """Lazy import of server.App."""
9
- try:
10
- from server.app import App
11
- return App()
12
- except ImportError as e:
13
- print(f"Warning: Could not import server.App: {e}", file=sys.stderr)
14
- return None
15
-
16
-
17
- def _get_task_registry():
18
- """Lazy import of task registry."""
19
- try:
20
- from tasks import TASKS as TASKS_DEFS
21
- return TASKS_DEFS
22
- except ImportError as e:
23
- print(f"Warning: Could not import TASKS: {e}", file=sys.stderr)
24
- return []
25
-
26
-
27
- def get_task(task_id: str, *, task_def: Optional[dict] = None) -> dict:
28
- """Get a task definition by ID."""
29
- if task_def:
30
- return task_def
31
- from tasks import TASK_MAP
32
- return TASK_MAP.get(task_id, {})
33
-
34
-
35
- # Define task definitions
36
- TASKS = [
37
- {
38
- "id": "easy",
39
- "task_id": "easy",
40
- "name": "easy",
41
- "title": "Single Query Routing",
42
- "difficulty": "easy",
43
- "description": "Route a single LLM query to the optimal model tier while minimising carbon footprint and latency.",
44
- "max_steps": 10,
45
- "grader": None,
46
- "grader_path": "graders:grade_easy",
47
- "graders": [],
48
- "grader_paths": [],
49
- "reward_range": [0.0, 1.0],
50
- },
51
- {
52
- "id": "medium",
53
- "task_id": "medium",
54
- "name": "medium",
55
- "title": "Multi-Query Episode",
56
- "difficulty": "medium",
57
- "description": "Route 3 queries of varying complexity.",
58
- "max_steps": 20,
59
- "grader": None,
60
- "grader_path": "graders:grade_medium",
61
- "graders": [],
62
- "grader_paths": [],
63
- "reward_range": [0.0, 1.0],
64
- },
65
- {
66
- "id": "hard",
67
- "task_id": "hard",
68
- "name": "hard",
69
- "title": "Stateful Carbon-Aware Routing",
70
- "difficulty": "hard",
71
- "description": "5-query episode with caching, KB lookups, cascade strategies, and carbon-aware waiting.",
72
- "max_steps": 50,
73
- "grader": None,
74
- "grader_path": "graders:grade_hard",
75
- "graders": [],
76
- "grader_paths": [],
77
- "reward_range": [0.0, 1.0],
78
- },
79
- ]
80
-
81
- # Build TASK_MAP
82
- TASK_MAP = {task["task_id"]: task for task in TASKS}
83
-
84
-
85
- def _get_task_map():
86
- """Lazy import of TASK_MAP."""
87
- return TASK_MAP
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Deterministic task definitions for the Eco-LLM routing environment."""
2
 
3
  from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+
7
+ from server.models import ModelChoice
8
+
9
+
10
+ ENERGY_COSTS = {
11
+ ModelChoice.SMALL: 0.1,
12
+ ModelChoice.MEDIUM: 0.3,
13
+ ModelChoice.LARGE: 0.6,
14
+ }
15
+
16
+ LATENCY_COSTS = {
17
+ ModelChoice.SMALL: 1.0,
18
+ ModelChoice.MEDIUM: 2.0,
19
+ ModelChoice.LARGE: 5.0,
20
+ }
21
+
22
+ MODEL_ORDER = [ModelChoice.SMALL, ModelChoice.MEDIUM, ModelChoice.LARGE]
23
+ MODEL_RANK = {model: index for index, model in enumerate(MODEL_ORDER)}
24
+ CARBON_SCHEDULE = [0.8, 0.6, 0.4, 0.3, 0.5]
25
+ LATENCY_MU = 0.1
26
+ MAX_CARBON_PENALTY = 0.8
27
+ KB_ENERGY_COST = 0.05
28
+ KB_LATENCY_COST = 1.5
29
+ MAX_STEPS_PER_EPISODE = 50
30
+
31
+
32
+ @dataclass(frozen=True)
33
+ class QuerySpec:
34
+ text: str
35
+ correct_answer: str
36
+ minimum_model: ModelChoice
37
+ kb_available: bool = False
38
+
39
+
40
+ @dataclass(frozen=True)
41
+ class TaskSpec:
42
+ task_id: str
43
+ difficulty: str
44
+ queries: tuple[QuerySpec, ...]
45
+ large_model_penalty: float = 0.0
46
+ description: str = ""
47
+
48
+
49
+ TASKS: dict[str, TaskSpec] = {
50
+ "task_1": TaskSpec(
51
+ task_id="task_1",
52
+ difficulty="easy",
53
+ queries=(
54
+ QuerySpec(
55
+ text="What is the most efficient insulation material for a passive house retrofit?",
56
+ correct_answer="Vacuum insulated panels",
57
+ minimum_model=ModelChoice.MEDIUM,
58
+ ),
59
+ ),
60
+ description="Single-query routing with accuracy-only emphasis.",
61
+ ),
62
+ "task_2": TaskSpec(
63
+ task_id="task_2",
64
+ difficulty="medium",
65
+ queries=(
66
+ QuerySpec(
67
+ text="Summarize the trade-off between quantization and factual accuracy in a customer support bot.",
68
+ correct_answer="Aggressive quantization lowers energy use but can reduce factual reliability.",
69
+ minimum_model=ModelChoice.SMALL,
70
+ ),
71
+ QuerySpec(
72
+ text="Explain when speculative decoding improves throughput on medium-sized models.",
73
+ correct_answer="It helps when draft tokens are likely to be accepted by the target model.",
74
+ minimum_model=ModelChoice.MEDIUM,
75
+ ),
76
+ QuerySpec(
77
+ text="Design a safety fallback for multilingual medical triage.",
78
+ correct_answer="Use high-capability review with escalation and verified retrieval before final output.",
79
+ minimum_model=ModelChoice.LARGE,
80
+ ),
81
+ ),
82
+ large_model_penalty=-0.2,
83
+ description="Three-query episode with an extra penalty for using the LARGE model.",
84
+ ),
85
+ "task_3": TaskSpec(
86
+ task_id="task_3",
87
+ difficulty="hard",
88
+ queries=(
89
+ QuerySpec(
90
+ text="Classify whether this FAQ request can be answered from the billing knowledge base.",
91
+ correct_answer="Yes, use the billing KB article.",
92
+ minimum_model=ModelChoice.SMALL,
93
+ kb_available=True,
94
+ ),
95
+ QuerySpec(
96
+ text="Route a long-form reasoning question about carbon-aware serving policy.",
97
+ correct_answer="Use cascade with escalation to a larger model if smaller ones fail.",
98
+ minimum_model=ModelChoice.MEDIUM,
99
+ ),
100
+ QuerySpec(
101
+ text="Classify whether this FAQ request can be answered from the billing knowledge base.",
102
+ correct_answer="Yes, use the billing KB article.",
103
+ minimum_model=ModelChoice.SMALL,
104
+ kb_available=True,
105
+ ),
106
+ QuerySpec(
107
+ text="Generate a compliant answer for a finance-regulated enterprise user.",
108
+ correct_answer="Use the large model with a retrieval-backed compliance layer.",
109
+ minimum_model=ModelChoice.LARGE,
110
+ ),
111
+ QuerySpec(
112
+ text="Route a long-form reasoning question about carbon-aware serving policy.",
113
+ correct_answer="Use cascade with escalation to a larger model if smaller ones fail.",
114
+ minimum_model=ModelChoice.MEDIUM,
115
+ ),
116
+ ),
117
+ description="Stateful five-query episode with repeats, caching, cascading, early exit, and waiting.",
118
+ ),
119
+ }
120
+
121
+ TASK_ALIASES: dict[str, str] = {
122
+ "easy": "task_1",
123
+ "medium": "task_2",
124
+ "hard": "task_3",
125
+ }
126
+
127
+
128
+ def get_task(task_id: str) -> TaskSpec:
129
+ """Return a task by id, defaulting to the easy task for unknown ids."""
130
+ resolved_task_id = TASK_ALIASES.get(task_id, task_id)
131
+ return TASKS.get(resolved_task_id, TASKS["task_1"])