gani2004 commited on
Commit
21cfa13
Β·
1 Parent(s): 8245662

Fix score range validation and update deployment config

Browse files
Files changed (3) hide show
  1. inference.py +34 -3
  2. privexa_medcodel +1 -0
  3. server/my_env_environment.py +28 -6
inference.py CHANGED
@@ -12,6 +12,7 @@ Usage:
12
  """
13
 
14
  import json
 
15
  import os
16
  import re
17
  import signal
@@ -47,6 +48,23 @@ MAX_RETRIES = 2
47
  # Global timeout safety (inference must complete in < 20 minutes)
48
  MAX_RUNTIME_SECONDS = int(os.environ.get("MAX_RUNTIME_SECONDS", "1100")) # ~18.3 min
49
  _start_time = time.time()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
 
51
 
52
  class TeeStream:
@@ -321,6 +339,7 @@ def log_start(task_id: str, metadata: Optional[dict] = None):
321
 
322
  def log_step(task_id: str, step: int, action: dict, reward: float, done: bool, info: Optional[dict] = None):
323
  """Emit a [STEP] structured log line."""
 
324
  entry = {
325
  "task_id": task_id,
326
  "step": step,
@@ -335,6 +354,7 @@ def log_step(task_id: str, step: int, action: dict, reward: float, done: bool, i
335
 
336
  def log_end(task_id: str, reward: float, metadata: Optional[dict] = None):
337
  """Emit an [END] structured log line."""
 
338
  entry = {
339
  "task_id": task_id,
340
  "reward": reward,
@@ -416,7 +436,7 @@ def run_evaluation():
416
  # Step the environment
417
  try:
418
  result_obs = env.step(med_action)
419
- score = result_obs.reward if result_obs.reward is not None else 0.0
420
  done = result_obs.done if result_obs.done is not None else True
421
  difficulty_scores.append(score)
422
  all_scores.append(score)
@@ -454,8 +474,19 @@ def run_evaluation():
454
 
455
  except Exception as e:
456
  print(f" βœ— Step failed: {e}")
457
- difficulty_scores.append(0.0)
458
- all_scores.append(0.0)
 
 
 
 
 
 
 
 
 
 
 
459
 
460
  # ── [STEP] with failure ──
461
  log_step(
 
12
  """
13
 
14
  import json
15
+ import math
16
  import os
17
  import re
18
  import signal
 
48
  # Global timeout safety (inference must complete in < 20 minutes)
49
  MAX_RUNTIME_SECONDS = int(os.environ.get("MAX_RUNTIME_SECONDS", "1100")) # ~18.3 min
50
  _start_time = time.time()
51
+ SCORE_EPSILON = 1e-4
52
+
53
+
54
+ def to_open_interval_score(value: float) -> float:
55
+ """Map scores to strict open interval (0, 1) for validator compliance."""
56
+ try:
57
+ score = float(value)
58
+ except (TypeError, ValueError):
59
+ score = 0.0
60
+
61
+ if not math.isfinite(score):
62
+ score = 0.0
63
+ if score <= 0.0:
64
+ return SCORE_EPSILON
65
+ if score >= 1.0:
66
+ return 1.0 - SCORE_EPSILON
67
+ return score
68
 
69
 
70
  class TeeStream:
 
339
 
340
  def log_step(task_id: str, step: int, action: dict, reward: float, done: bool, info: Optional[dict] = None):
341
  """Emit a [STEP] structured log line."""
342
+ reward = round(to_open_interval_score(reward), 4)
343
  entry = {
344
  "task_id": task_id,
345
  "step": step,
 
354
 
355
  def log_end(task_id: str, reward: float, metadata: Optional[dict] = None):
356
  """Emit an [END] structured log line."""
357
+ reward = round(to_open_interval_score(reward), 4)
358
  entry = {
359
  "task_id": task_id,
360
  "reward": reward,
 
436
  # Step the environment
437
  try:
438
  result_obs = env.step(med_action)
439
+ score = to_open_interval_score(result_obs.reward if result_obs.reward is not None else 0.0)
440
  done = result_obs.done if result_obs.done is not None else True
441
  difficulty_scores.append(score)
442
  all_scores.append(score)
 
474
 
475
  except Exception as e:
476
  print(f" βœ— Step failed: {e}")
477
+ fallback_score = to_open_interval_score(0.0)
478
+ difficulty_scores.append(fallback_score)
479
+ all_scores.append(fallback_score)
480
+
481
+ # ── [STEP] with failure ──
482
+ log_step(
483
+ task_id=task_id,
484
+ step=i + 1,
485
+ action=action_dict,
486
+ reward=fallback_score,
487
+ done=True,
488
+ info={"error": str(e)},
489
+ )
490
 
491
  # ── [STEP] with failure ──
492
  log_step(
privexa_medcodel ADDED
@@ -0,0 +1 @@
 
 
1
+ Subproject commit 8245662c88fe44d8cf65bd2b71ecae28d4f5216c
server/my_env_environment.py CHANGED
@@ -18,6 +18,7 @@ Contains: environment logic, deterministic grader, shaped rewards, action valida
18
  """
19
 
20
  import json
 
21
  import os
22
  import re
23
  from typing import Any, Dict, List, Optional, Set, Tuple
@@ -56,6 +57,23 @@ def _load_task_cases(difficulty: str) -> List[Dict[str, Any]]:
56
  ICD10_PATTERN = re.compile(r"^[A-Z]\d{2}(\.\d{1,4})?$", re.IGNORECASE)
57
  CPT_PATTERN = re.compile(r"^\d{5}$")
58
  HCPCS_PATTERN = re.compile(r"^[A-Z]\d{4}$", re.IGNORECASE)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
 
60
 
61
  def _validate_action(action_dict: dict) -> Tuple[bool, List[str]]:
@@ -213,7 +231,7 @@ def _grade(action_dict: dict, ground_truth: dict) -> Dict[str, float]:
213
  )
214
 
215
  return {
216
- "score": round(min(1.0, max(0.0, total)), 4),
217
  "diagnosis_accuracy": round(diag_score, 4),
218
  "procedure_accuracy": round(proc_score, 4),
219
  "decision_accuracy": round(dec_score, 4),
@@ -277,7 +295,7 @@ def _compute_reward(action_dict: dict, ground_truth: dict, difficulty: str = "ea
277
  diff_mult = {"easy": 0.8, "medium": 1.0, "hard": 1.2}.get(difficulty, 1.0)
278
  total_penalty = sum(penalties.values()) * diff_mult
279
  total_bonus = sum(bonuses.values())
280
- final = max(0.0, min(1.0, base + total_penalty + total_bonus))
281
 
282
  feedback_parts = []
283
  if penalties:
@@ -413,7 +431,11 @@ class MyEnvironment(Environment):
413
 
414
  self._current_case = self._pick_case(task_id)
415
 
416
- return self._build_observation(self._current_case, done=False, reward=0.0)
 
 
 
 
417
 
418
  def step(self, action: MedAction) -> MedObservation: # type: ignore[override]
419
  """
@@ -429,7 +451,7 @@ class MyEnvironment(Environment):
429
  return self._build_observation(
430
  self._current_case or {},
431
  done=True,
432
- reward=0.0,
433
  feedback="Episode already done. Call reset().",
434
  )
435
 
@@ -456,7 +478,7 @@ class MyEnvironment(Environment):
456
  return self._build_observation(
457
  self._current_case or {},
458
  done=self._done,
459
- reward=0.0,
460
  feedback=f"Invalid action: {'; '.join(errors)}",
461
  )
462
 
@@ -467,7 +489,7 @@ class MyEnvironment(Environment):
467
  self._action_history.append({"action": action_dict, "valid": True})
468
  self._done = True # single-step episode for valid actions
469
 
470
- score = reward_result["score"]
471
 
472
  return self._build_observation(
473
  self._current_case or {},
 
18
  """
19
 
20
  import json
21
+ import math
22
  import os
23
  import re
24
  from typing import Any, Dict, List, Optional, Set, Tuple
 
57
  ICD10_PATTERN = re.compile(r"^[A-Z]\d{2}(\.\d{1,4})?$", re.IGNORECASE)
58
  CPT_PATTERN = re.compile(r"^\d{5}$")
59
  HCPCS_PATTERN = re.compile(r"^[A-Z]\d{4}$", re.IGNORECASE)
60
+ SCORE_EPSILON = 1e-4
61
+
62
+
63
+ def _to_open_interval_score(value: float) -> float:
64
+ """Map a score to the strict open interval (0, 1)."""
65
+ try:
66
+ score = float(value)
67
+ except (TypeError, ValueError):
68
+ score = 0.0
69
+
70
+ if not math.isfinite(score):
71
+ score = 0.0
72
+ if score <= 0.0:
73
+ return SCORE_EPSILON
74
+ if score >= 1.0:
75
+ return 1.0 - SCORE_EPSILON
76
+ return score
77
 
78
 
79
  def _validate_action(action_dict: dict) -> Tuple[bool, List[str]]:
 
231
  )
232
 
233
  return {
234
+ "score": round(_to_open_interval_score(total), 4),
235
  "diagnosis_accuracy": round(diag_score, 4),
236
  "procedure_accuracy": round(proc_score, 4),
237
  "decision_accuracy": round(dec_score, 4),
 
295
  diff_mult = {"easy": 0.8, "medium": 1.0, "hard": 1.2}.get(difficulty, 1.0)
296
  total_penalty = sum(penalties.values()) * diff_mult
297
  total_bonus = sum(bonuses.values())
298
+ final = _to_open_interval_score(base + total_penalty + total_bonus)
299
 
300
  feedback_parts = []
301
  if penalties:
 
431
 
432
  self._current_case = self._pick_case(task_id)
433
 
434
+ return self._build_observation(
435
+ self._current_case,
436
+ done=False,
437
+ reward=_to_open_interval_score(0.0),
438
+ )
439
 
440
  def step(self, action: MedAction) -> MedObservation: # type: ignore[override]
441
  """
 
451
  return self._build_observation(
452
  self._current_case or {},
453
  done=True,
454
+ reward=_to_open_interval_score(0.0),
455
  feedback="Episode already done. Call reset().",
456
  )
457
 
 
478
  return self._build_observation(
479
  self._current_case or {},
480
  done=self._done,
481
+ reward=_to_open_interval_score(0.0),
482
  feedback=f"Invalid action: {'; '.join(errors)}",
483
  )
484
 
 
489
  self._action_history.append({"action": action_dict, "valid": True})
490
  self._done = True # single-step episode for valid actions
491
 
492
+ score = _to_open_interval_score(reward_result["score"])
493
 
494
  return self._build_observation(
495
  self._current_case or {},