rudhratej09 commited on
Commit
deebc89
Β·
verified Β·
1 Parent(s): 342dbfd

Update inference.py

Browse files
Files changed (1) hide show
  1. inference.py +135 -11
inference.py CHANGED
@@ -7,7 +7,7 @@ Environment variables:
7
  HF_TOKEN Your HuggingFace API key (REQUIRED, no default)
8
  API_BASE_URL LLM endpoint (default: https://router.huggingface.co/v1)
9
  MODEL_NAME Model identifier (default: Qwen/Qwen2.5-72B-Instruct)
10
- ECO_LLM_TASK Task to run (default: task_1 | task_2 | task_3 | all)
11
 
12
  Stdout format (mandatory):
13
  [START] task=<task> env=eco_llm_inference_routing model=<model>
@@ -32,7 +32,10 @@ import json
32
  import os
33
  import re
34
  import textwrap
35
- from typing import List, Optional
 
 
 
36
 
37
  from openai import OpenAI
38
 
@@ -42,8 +45,9 @@ HF_TOKEN: Optional[str] = os.getenv("HF_TOKEN")
42
  API_KEY: Optional[str] = HF_TOKEN or os.getenv("OPENAI_API_KEY")
43
  API_BASE_URL: str = os.getenv("API_BASE_URL", "https://router.huggingface.co/v1")
44
  MODEL_NAME: str = os.getenv("MODEL_NAME", "Qwen/Qwen2.5-72B-Instruct")
45
- TASK_ID: str = os.getenv("ECO_LLM_TASK", "task_1")
46
  BENCHMARK: str = "eco_llm_inference_routing"
 
47
 
48
  MAX_STEPS: int = 50
49
  SUCCESS_SCORE_THRESHOLD: float = 0.5
@@ -52,7 +56,6 @@ MAX_TOKENS: int = 80
52
 
53
  # Max reward per query step = score(1.0) + cache_bonus(0.5) = 1.5
54
  _MAX_REWARD_PER_STEP: float = 1.5
55
- TASK_QUERY_COUNTS: dict[str, int] = {"task_1": 1, "task_2": 3, "task_3": 5}
56
 
57
  SYSTEM_PROMPT = textwrap.dedent("""
58
  You are an LLM inference router for the Eco-LLM environment.
@@ -131,6 +134,128 @@ def sanitize_field(value: Optional[str]) -> str:
131
  return compact if compact else "null"
132
 
133
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  # ── LLM action ───────────────────────────────────────────────────────────────
135
 
136
  def build_user_prompt(
@@ -236,13 +361,13 @@ async def run_episode(client: OpenAI, task_id: str) -> float:
236
  score: float = 0.0 # ← key fix
237
 
238
  # Compute max reward for THIS task (not at module load)
239
- max_total: float = TASK_QUERY_COUNTS.get(task_id, 5) * _MAX_REWARD_PER_STEP
240
 
241
  # Try AsyncEnvClient (HF Space), fall back to local env
242
  env = None
243
  try:
244
  from openenv.client import AsyncEnvClient # type: ignore
245
- env = AsyncEnvClient(base_url=os.getenv("ENV_BASE_URL", "http://localhost:7860"))
246
  except Exception:
247
  from server.env import EcoLLMInferenceRoutingEnvironment # type: ignore
248
  env = EcoLLMInferenceRoutingEnvironment()
@@ -341,12 +466,11 @@ def main() -> None:
341
  )
342
  client = OpenAI(base_url=API_BASE_URL, api_key=API_KEY)
343
 
344
- # ECO_LLM_TASK=all runs all three tasks sequentially
345
- tasks = ["task_1", "task_2", "task_3"] if TASK_ID == "all" \
346
- else [TASK_ID if TASK_ID in TASK_QUERY_COUNTS else "task_1"]
347
 
348
- for t in tasks:
349
- asyncio.run(run_episode(client, t))
350
 
351
 
352
  if __name__ == "__main__":
 
7
  HF_TOKEN Your HuggingFace API key (REQUIRED, no default)
8
  API_BASE_URL LLM endpoint (default: https://router.huggingface.co/v1)
9
  MODEL_NAME Model identifier (default: Qwen/Qwen2.5-72B-Instruct)
10
+ ECO_LLM_TASK Task selector (default: all discovered tasks)
11
 
12
  Stdout format (mandatory):
13
  [START] task=<task> env=eco_llm_inference_routing model=<model>
 
32
  import os
33
  import re
34
  import textwrap
35
+ from pathlib import Path
36
+ from typing import Any, List, Optional
37
+ from urllib.error import HTTPError, URLError
38
+ from urllib.request import urlopen
39
 
40
  from openai import OpenAI
41
 
 
45
  API_KEY: Optional[str] = HF_TOKEN or os.getenv("OPENAI_API_KEY")
46
  API_BASE_URL: str = os.getenv("API_BASE_URL", "https://router.huggingface.co/v1")
47
  MODEL_NAME: str = os.getenv("MODEL_NAME", "Qwen/Qwen2.5-72B-Instruct")
48
+ TASK_ID: str = os.getenv("ECO_LLM_TASK", "all")
49
  BENCHMARK: str = "eco_llm_inference_routing"
50
+ ENV_BASE_URL: str = os.getenv("ENV_BASE_URL", "http://localhost:7860")
51
 
52
  MAX_STEPS: int = 50
53
  SUCCESS_SCORE_THRESHOLD: float = 0.5
 
56
 
57
  # Max reward per query step = score(1.0) + cache_bonus(0.5) = 1.5
58
  _MAX_REWARD_PER_STEP: float = 1.5
 
59
 
60
  SYSTEM_PROMPT = textwrap.dedent("""
61
  You are an LLM inference router for the Eco-LLM environment.
 
134
  return compact if compact else "null"
135
 
136
 
137
+ def _extract_task_ids(payload: Any) -> List[str]:
138
+ if isinstance(payload, dict):
139
+ if isinstance(payload.get("tasks"), list):
140
+ return _extract_task_ids(payload["tasks"])
141
+ for key in ("available_task_ids", "task_ids"):
142
+ values = payload.get(key)
143
+ if isinstance(values, list):
144
+ return [str(value).strip() for value in values if str(value).strip()]
145
+ return []
146
+
147
+ if not isinstance(payload, list):
148
+ return []
149
+
150
+ task_ids: List[str] = []
151
+ for item in payload:
152
+ if isinstance(item, str) and item.strip():
153
+ task_ids.append(item.strip())
154
+ continue
155
+ if not isinstance(item, dict):
156
+ continue
157
+ for key in ("task_id", "id", "name"):
158
+ value = item.get(key)
159
+ if value and str(value).strip():
160
+ task_ids.append(str(value).strip())
161
+ break
162
+ return task_ids
163
+
164
+
165
+ def _dedupe_task_ids(task_ids: List[str]) -> List[str]:
166
+ deduped: List[str] = []
167
+ seen: set[str] = set()
168
+ for task_id in task_ids:
169
+ clean = task_id.strip()
170
+ if not clean or clean in seen:
171
+ continue
172
+ seen.add(clean)
173
+ deduped.append(clean)
174
+ return deduped
175
+
176
+
177
+ def _fetch_json(url: str) -> Optional[Any]:
178
+ try:
179
+ with urlopen(url, timeout=3) as response:
180
+ charset = response.headers.get_content_charset() or "utf-8"
181
+ return json.loads(response.read().decode(charset))
182
+ except (HTTPError, URLError, TimeoutError, json.JSONDecodeError, OSError):
183
+ return None
184
+
185
+
186
+ def discover_task_ids() -> List[str]:
187
+ remote_candidates = [
188
+ f"{ENV_BASE_URL.rstrip('/')}/tasks",
189
+ f"{ENV_BASE_URL.rstrip('/')}/tasks/meta",
190
+ f"{ENV_BASE_URL.rstrip('/')}/task_ids",
191
+ f"{ENV_BASE_URL.rstrip('/')}/metadata",
192
+ ]
193
+ for url in remote_candidates:
194
+ payload = _fetch_json(url)
195
+ task_ids = _dedupe_task_ids(_extract_task_ids(payload))
196
+ if task_ids:
197
+ return task_ids
198
+
199
+ try:
200
+ from tasks import TASKS as VALIDATOR_TASKS # type: ignore
201
+
202
+ task_ids = _dedupe_task_ids(_extract_task_ids(VALIDATOR_TASKS))
203
+ if task_ids:
204
+ return task_ids
205
+ except Exception:
206
+ pass
207
+
208
+ try:
209
+ from server.tasks import TASKS as SERVER_TASKS # type: ignore
210
+
211
+ task_ids = _dedupe_task_ids(list(SERVER_TASKS.keys()))
212
+ if task_ids:
213
+ return task_ids
214
+ except Exception:
215
+ pass
216
+
217
+ manifest_path = Path(__file__).with_name("openenv.yaml")
218
+ if manifest_path.exists():
219
+ raw_lines = manifest_path.read_text(encoding="utf-8").splitlines()
220
+ task_ids: List[str] = []
221
+ for line in raw_lines:
222
+ stripped = line.strip()
223
+ if stripped.startswith("task_id:"):
224
+ task_ids.append(stripped.split(":", 1)[1].strip())
225
+ task_ids = _dedupe_task_ids(task_ids)
226
+ if task_ids:
227
+ return task_ids
228
+
229
+ return ["task_1"]
230
+
231
+
232
+ def resolve_task_ids(task_selector: str) -> List[str]:
233
+ available_tasks = discover_task_ids()
234
+ selector = task_selector.strip()
235
+
236
+ if not selector or selector.lower() == "all":
237
+ return available_tasks
238
+
239
+ requested_tasks = [part.strip() for part in selector.split(",") if part.strip()]
240
+ return requested_tasks or available_tasks
241
+
242
+
243
+ def get_task_query_count(task_id: str) -> int:
244
+ try:
245
+ from server.tasks import TASKS as SERVER_TASKS, TASK_ALIASES # type: ignore
246
+
247
+ resolved_task_id = TASK_ALIASES.get(task_id, task_id)
248
+ task_spec = SERVER_TASKS.get(resolved_task_id)
249
+ if task_spec is not None:
250
+ queries = getattr(task_spec, "queries", ())
251
+ if queries:
252
+ return len(queries)
253
+ except Exception:
254
+ pass
255
+
256
+ return 1
257
+
258
+
259
  # ── LLM action ───────────────────────────────────────────────────────────────
260
 
261
  def build_user_prompt(
 
361
  score: float = 0.0 # ← key fix
362
 
363
  # Compute max reward for THIS task (not at module load)
364
+ max_total: float = get_task_query_count(task_id) * _MAX_REWARD_PER_STEP
365
 
366
  # Try AsyncEnvClient (HF Space), fall back to local env
367
  env = None
368
  try:
369
  from openenv.client import AsyncEnvClient # type: ignore
370
+ env = AsyncEnvClient(base_url=ENV_BASE_URL)
371
  except Exception:
372
  from server.env import EcoLLMInferenceRoutingEnvironment # type: ignore
373
  env = EcoLLMInferenceRoutingEnvironment()
 
466
  )
467
  client = OpenAI(base_url=API_BASE_URL, api_key=API_KEY)
468
 
469
+ async def run_tasks() -> None:
470
+ for task_id in resolve_task_ids(TASK_ID):
471
+ await run_episode(client, task_id)
472
 
473
+ asyncio.run(run_tasks())
 
474
 
475
 
476
  if __name__ == "__main__":