Ryz3n758 commited on
Commit
236fdec
·
verified ·
1 Parent(s): 0481c87

Upload folder using huggingface_hub

Browse files
Files changed (4) hide show
  1. grader.py +1 -1
  2. guidelines.txt +113 -0
  3. inference.py +15 -3
  4. server/layout_environment.py +1 -1
grader.py CHANGED
@@ -20,7 +20,7 @@ class TaskGrade:
20
  q_delta: float
21
 
22
 
23
- OPEN_INTERVAL_EPS = 1e-2
24
 
25
 
26
  def _clamp01(x: float) -> float:
 
20
  q_delta: float
21
 
22
 
23
+ OPEN_INTERVAL_EPS = 5e-2
24
 
25
 
26
  def _clamp01(x: float) -> float:
guidelines.txt ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 🚀 Hackathon Submission Guidelines (OpenEnv RL Challenge)
2
+ 1. Project Structure
3
+ Your inference script must be named inference.py
4
+ It must be located in the root directory of your project
5
+
6
+
7
+
8
+ 2. LLM Usage Requirements
9
+ You must use the OpenAI Client for all LLM calls
10
+ Do not use alternative SDKs or direct HTTP calls
11
+
12
+
13
+
14
+ 3. Required Environment Variables
15
+ Your inference.py must read the following environment variables:
16
+ API_BASE_URL
17
+ Description: API endpoint for the LLM
18
+ Requirement: Must include a default value
19
+ MODEL_NAME
20
+ Description: Model identifier used for inference
21
+ Requirement: Must include a default value
22
+ HF_TOKEN
23
+ Description: Hugging Face API token
24
+ Requirement: Mandatory (no default required)
25
+
26
+ 4. INFERENCE OUTPUT FORMAT
27
+ The script must emit exactly three line types to stdout, in this order:
28
+ [START] task=<task_name> env=<benchmark> model=<model_name>
29
+ [STEP] step=<n> action=<action_str> reward=<0.00> done=<true|false> error=<msg|null>
30
+ [END] success=<true|false> steps=<n> rewards=<r1,r2,...,rn>
31
+
32
+
33
+
34
+ Rules:
35
+ - One [START] line at episode begin.
36
+ - One [STEP] line per step, immediately after env.step() returns.
37
+ - One [END] line after env.close(), always emitted (even on exception).
38
+ - reward and rewards are formatted to 2 decimal places.
39
+ - done and success are lowercase booleans: true or false.
40
+ - error is the raw last_action_error string, or null if none.
41
+ - All fields on a single line with no newlines within a line.
42
+ Example:
43
+ [START] task=click-test env=miniwob model=Qwen3-VL-30B
44
+ [STEP] step=1 action=click('123') reward=0.00 done=false error=null
45
+ [STEP] step=2 action=fill('456','text') reward=0.00 done=false error=null
46
+ [STEP] step=3 action=click('789') reward=1.00 done=true error=null
47
+ [END] success=true steps=3 rewards=0.00,0.00,1.00
48
+ ✅ Example (inference.py)
49
+ import os
50
+ from openai import OpenAI
51
+
52
+ # Read environment variables with defaults where required
53
+ API_BASE_URL = os.getenv("API_BASE_URL", "https://api.openai.com/v1")
54
+ MODEL_NAME = os.getenv("MODEL_NAME", "gpt-4.1-mini")
55
+ HF_TOKEN = os.getenv("HF_TOKEN")
56
+
57
+ if HF_TOKEN is None:
58
+ raise ValueError("HF_TOKEN environment variable is required")
59
+
60
+ # Initialize OpenAI client
61
+ client = OpenAI(
62
+ base_url=API_BASE_URL,
63
+ api_key=HF_TOKEN
64
+ )
65
+
66
+ def run_inference(prompt: str):
67
+ response = client.chat.completions.create(
68
+ model=MODEL_NAME,
69
+ messages=[
70
+ {"role": "user", "content": prompt}
71
+ ]
72
+ )
73
+ response = response.choices[0].message.content
74
+ # Print output based on above given format
75
+
76
+
77
+ if __name__ == "__main__":
78
+ print(run_inference("Hello from OpenEnv!"))
79
+
80
+ 4. Hugging Face Space Guidelines
81
+ Building a Hugging Face Space can take significant time, especially if multiple spaces are active
82
+ To avoid delays:
83
+ Turn off all unnecessary spaces
84
+ Keep only your primary submission space running
85
+
86
+ 5. Submission Validation Rules
87
+ The system will check if your Hugging Face Space is live
88
+ If your space is not in a running state, your submission will fail automatically
89
+ Before submitting:
90
+ Ensure your space is fully built
91
+ Confirm it is in the “Running” state
92
+
93
+ 6. Hardware Requirements
94
+ Your solution will be executed inside a Docker container with limited resources
95
+ It must run within the following constraints:
96
+ 2 vCPU
97
+ 8 GB RAM
98
+ 👉 Ensure your model, dependencies, and runtime fit within these limits. Submissions exceeding these constraints may fail during evaluation.
99
+
100
+ 6. Resubmissions
101
+ You are allowed to resubmit your project multiple times
102
+ If your submission fails validation, you can:
103
+ Fix the issues
104
+ Ensure your Hugging Face Space is running
105
+ Submit again
106
+ 👉 There is no penalty for resubmitting, so iterate until your submission passes all checks.
107
+
108
+ ⚠️ Common Failure Cases (Avoid These)
109
+ inference.py not in root directory
110
+ Missing default values for API_BASE_URL or MODEL_NAME
111
+ Missing HF_TOKEN
112
+ Hugging Face Space still building during submission
113
+ Space stopped due to multiple active deployments
inference.py CHANGED
@@ -11,6 +11,7 @@ STDOUT FORMAT
11
  import argparse
12
  import asyncio
13
  import json
 
14
  import os
15
  import sys
16
  from pathlib import Path
@@ -39,6 +40,8 @@ BENCHMARK = os.getenv("LAYOUT_BENCHMARK", "layoutenv")
39
  TEMPERATURE = float(os.getenv("TEMPERATURE", "0.0"))
40
  MAX_TOKENS = 200
41
  SUCCESS_Q_DELTA = 0.1
 
 
42
  PRINT_SUMMARY_STDERR = os.getenv("PRINT_SUMMARY_STDERR", "0") == "1"
43
  EARLY_STOP_ON_SUCCESS = os.getenv("EARLY_STOP_ON_SUCCESS", "1") == "1"
44
 
@@ -67,21 +70,30 @@ def resolve_background_image_path(sample: Dict[str, Any], dataset_json_path: str
67
  return abs_path
68
 
69
 
 
 
 
 
 
 
 
70
  def log_start(task: str, env: str, model: str) -> None:
71
  print(f"[START] task={task} env={env} model={model}", flush=True)
72
 
73
 
74
  def log_step(step: int, action_str: str, reward: float, done: bool, error: Optional[str]) -> None:
75
  error_val = error if error else "null"
 
76
  print(
77
- f"[STEP] step={step} action={action_str} reward={reward:.2f} "
78
  f"done={str(done).lower()} error={error_val}",
79
  flush=True,
80
  )
81
 
82
 
83
  def log_end(success: bool, steps: int, rewards: List[float]) -> None:
84
- rewards_str = ",".join(f"{r:.2f}" for r in rewards)
 
85
  print(
86
  f"[END] success={str(success).lower()} steps={steps} rewards={rewards_str}",
87
  flush=True,
@@ -208,7 +220,7 @@ async def run_episode(
208
  action_str = action_to_string(action, raw)
209
  result = await env.step(action)
210
  obs = result.observation
211
- reward = result.reward or 0.0
212
  done = result.done
213
  raw_error = getattr(result, "last_action_error", None)
214
  if raw_error is None:
 
11
  import argparse
12
  import asyncio
13
  import json
14
+ import math
15
  import os
16
  import sys
17
  from pathlib import Path
 
40
  TEMPERATURE = float(os.getenv("TEMPERATURE", "0.0"))
41
  MAX_TOKENS = 200
42
  SUCCESS_Q_DELTA = 0.1
43
+ # Clamp epsilon — keep printed rewards strictly inside (0, 1).
44
+ _REWARD_EPS = 0.05
45
  PRINT_SUMMARY_STDERR = os.getenv("PRINT_SUMMARY_STDERR", "0") == "1"
46
  EARLY_STOP_ON_SUCCESS = os.getenv("EARLY_STOP_ON_SUCCESS", "1") == "1"
47
 
 
70
  return abs_path
71
 
72
 
73
+ def _clamp_reward(r: float) -> float:
74
+ """Ensure reward is strictly inside (0, 1) — never exact 0.0 or 1.0."""
75
+ if r is None or math.isnan(r) or math.isinf(r):
76
+ return 0.5
77
+ return min(max(float(r), _REWARD_EPS), 1.0 - _REWARD_EPS)
78
+
79
+
80
  def log_start(task: str, env: str, model: str) -> None:
81
  print(f"[START] task={task} env={env} model={model}", flush=True)
82
 
83
 
84
  def log_step(step: int, action_str: str, reward: float, done: bool, error: Optional[str]) -> None:
85
  error_val = error if error else "null"
86
+ safe_reward = _clamp_reward(reward)
87
  print(
88
+ f"[STEP] step={step} action={action_str} reward={safe_reward:.2f} "
89
  f"done={str(done).lower()} error={error_val}",
90
  flush=True,
91
  )
92
 
93
 
94
  def log_end(success: bool, steps: int, rewards: List[float]) -> None:
95
+ safe_rewards = [_clamp_reward(r) for r in rewards]
96
+ rewards_str = ",".join(f"{r:.2f}" for r in safe_rewards)
97
  print(
98
  f"[END] success={str(success).lower()} steps={steps} rewards={rewards_str}",
99
  flush=True,
 
220
  action_str = action_to_string(action, raw)
221
  result = await env.step(action)
222
  obs = result.observation
223
+ reward = _clamp_reward(result.reward)
224
  done = result.done
225
  raw_error = getattr(result, "last_action_error", None)
226
  if raw_error is None:
server/layout_environment.py CHANGED
@@ -503,7 +503,7 @@ TERMINAL_BONUS_SCALE = 5.0
503
  TERMINAL_PENALTY = -1.0
504
  # Align terminal shaping with the easiest grader delta threshold.
505
  Q_DELTA_THRESHOLD = 0.05
506
- VISIBLE_REWARD_EPS = 0.01
507
 
508
 
509
  def _normalize_visible_reward(raw_reward: float | int) -> float:
 
503
  TERMINAL_PENALTY = -1.0
504
  # Align terminal shaping with the easiest grader delta threshold.
505
  Q_DELTA_THRESHOLD = 0.05
506
+ VISIBLE_REWARD_EPS = 0.05
507
 
508
 
509
  def _normalize_visible_reward(raw_reward: float | int) -> float: