Smart_Routing_System / inference.py
rohanbelsare's picture
Fix: Added 3 tasks and clamped scores to 0.01-0.99 per Phase 2 rules
b7a2462
Raw History Blame Contribute Delete
5.1 kB
import asyncio
import os
import textwrap
import sys
import numpy as np
from typing import List, Optional
import torch
from openai import OpenAI
ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.join(ROOT_DIR, "openenv_env"))
sys.path.insert(0, os.path.join(ROOT_DIR, "rl"))
from healthcare_env import HealthcareRoutingEnv
from dqn_agent import DQNAgent
API_BASE_URL = os.getenv("API_BASE_URL", "https://api.openai.com/v1")
MODEL_NAME = os.getenv("MODEL_NAME", "gpt-3.5-turbo")
HF_TOKEN = os.getenv("HF_TOKEN", "dummy-token-if-empty")
BENCHMARK = "healthcare-routing"
MAX_STEPS = 10
# The 3 tasks we just created in task.py
TASKS = ["healthcare-routing-easy", "healthcare-routing-medium", "healthcare-routing-hard"]
def log_start(task: str, env: str, model: str) -> None:
print(f"[START] task={task} env={env} model={model}", flush=True)
def log_step(step: int, action: str, reward: float, done: bool, error: Optional[str]) -> None:
error_val = error if error else "null"
done_val = str(done).lower()
print(f"[STEP] step={step} action={action} reward={reward:.2f} done={done_val} error={error_val}", flush=True)
def log_end(success: bool, steps: int, score: float, rewards: List[float]) -> None:
rewards_str = ",".join(f"{r:.2f}" for r in rewards)
print(f"[END] success={str(success).lower()} steps={steps} score={score:.3f} rewards={rewards_str}", flush=True)
async def run_scenario(client: OpenAI, agent: DQNAgent, task_name: str) -> float:
env = HealthcareRoutingEnv()
rewards: List[float] = []
steps_taken = 0
success = False
log_start(task=task_name, env=BENCHMARK, model=MODEL_NAME)
try:
obs, info = env.reset()
for step in range(1, MAX_STEPS + 1):
try:
prompt = f"System state array: {obs.tolist()}. Give a 1-word strategy (e.g., 'Reroute' or 'Wait')."
response = await asyncio.to_thread(
client.chat.completions.create,
model=MODEL_NAME,
messages=[{"role": "user", "content": prompt}],
max_tokens=5,
temperature=0.0,
)
raw_response = response.choices[0].message.content.strip()
llm_strategy = raw_response.replace("`", "").strip()
except Exception:
llm_strategy = "Fallback"
try:
state_tensor = torch.FloatTensor(obs).unsqueeze(0)
net = getattr(agent, "model", getattr(agent, "policy_net", getattr(agent, "q_net", getattr(agent, "network", None))))
if net is not None:
with torch.no_grad():
q_values = net(state_tensor).cpu().numpy()[0]
NUM_HOSPITALS = 5
NUM_AMBULANCES = 4
for action_idx in range(NUM_HOSPITALS * NUM_AMBULANCES):
h_id = action_idx // NUM_AMBULANCES
a_id = action_idx % NUM_AMBULANCES
hospital_beds_norm = obs[4 + (h_id * 4)]
ambulance_available = obs[24 + (a_id * 2) + 1]
if hospital_beds_norm <= 0.0 or ambulance_available == 0.0:
q_values[action_idx] = -999999.0
action_int = int(np.argmax(q_values))
else:
action_int = env.get_greedy_action()
except Exception:
action_int = env.get_greedy_action()
obs, reward, terminated, truncated, info = env.step(action_int)
done = terminated or truncated
rewards.append(float(reward))
steps_taken = step
log_step(step=step, action=str(action_int), reward=float(reward), done=done, error=None)
if done:
break
total_reward = sum(rewards)
raw_score = total_reward / 800.0
# Phase 2 score clamping to strictly (0, 1)
score = min(max(raw_score, 0.01), 0.99)
success = any(r > 50 for r in rewards)
except Exception as e:
log_step(step=steps_taken + 1, action="-1", reward=0.0, done=True, error=str(e))
score = 0.01
success = False
finally:
env.close()
log_end(success=success, steps=steps_taken, score=score, rewards=rewards)
return score
async def main() -> None:
client = OpenAI(base_url=API_BASE_URL, api_key=HF_TOKEN)
env = HealthcareRoutingEnv()
obs_size = env.observation_space.shape[0]
action_size = env.action_space.n
agent = DQNAgent(obs_size, action_size)
model_path = os.path.join(ROOT_DIR, "rl", "models", "dqn_healthcare.pth")
if os.path.exists(model_path):
try:
agent.load(model_path)
except Exception as e:
print(f"[Warning] Could not load PyTorch weights. Error: {e}")
# Loop through the 3 required tasks
for task_name in TASKS:
await run_scenario(client, agent, task_name)
if __name__ == "__main__":
asyncio.run(main())