devils-agent / baim /evaluate_policy.py
devildasdf's picture
Upload experimental BAIM code, research checkpoints and measured evaluations
795f737 verified
Raw
History Blame Contribute Delete
4.19 kB
"""Single-step browser benchmark with independent fixture outcome checks."""
import argparse
import json
from pathlib import Path
import platform
import statistics
from time import perf_counter
import torch
from playwright.sync_api import sync_playwright
from .authority import Authority
from .browser import Browser
from .policy import LearnedPolicy
from .runtime import Runtime
from .synthetic import load, render
from .baseline import LexicalRoleBaseline
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--checkpoint',default='models/v000-mean')
parser.add_argument('--data',default='datasets/synthetic-v1/test.jsonl')
parser.add_argument('--output',default='reports/policy-browser-v000.json')
parser.add_argument('--limit',type=int,default=120)
parser.add_argument('--quantized',action='store_true')
parser.add_argument('--baseline',action='store_true')
args = parser.parse_args()
torch.set_num_threads(2)
torch.set_num_interop_threads(1)
start = perf_counter()
policy = LexicalRoleBaseline() if args.baseline else LearnedPolicy(args.checkpoint,quantized=args.quantized)
load_ms = (perf_counter()-start)*1000
results = []
with sync_playwright() as pw:
with pw.chromium.launch(headless=True) as chromium:
context = chromium.new_context(viewport={'width':1100,'height':900})
browser = Browser(context)
authority = Authority()
for sample in load(args.data)[:args.limit]:
browser.page.set_content(render(sample))
authority.replace(sample['goal'])
start = perf_counter()
state = browser.observe()
observed_ms = (perf_counter()-start)*1000
start = perf_counter()
decision = policy.predict(sample['goal'],state,authority.ticket(state))
policy_ms = (perf_counter()-start)*1000
runtime = Runtime(browser,authority,lambda *_: True)
outcome = runtime.execute(decision)
expected = sample['target']
if sample['action'] == 'C':
success = browser.page.evaluate('window.fixtureResult') == expected
else:
# data-index is used only by the evaluator; never shown to the policy.
value = browser.page.locator(f'[data-index="{expected}"]').input_value()
success = value == sample['argument']
results.append(dict(sample_id=sample['sample_id'],template=sample['template'],
success=success,abstained=decision.action.kind.value=='A',
expected_action=sample['action'],predicted_action=decision.action.kind.value,
action_confidence=decision.action_confidence,target_confidence=decision.target_confidence,
observation_ms=observed_ms,policy_ms=policy_ms,execution_ms=outcome.wall_ms,
status=outcome.status,code=outcome.code))
if len(results)%20==0:
print(f'{len(results)} fixtures complete',flush=True)
context.close()
def median(key):
return statistics.median(row[key] for row in results)
report = dict(checkpoint='lexical-role-baseline' if args.baseline else args.checkpoint,quantized=args.quantized,platform=platform.platform(),
torch_threads=2,model_load_ms=load_ms,samples=len(results),
success_rate=sum(r['success'] for r in results)/len(results),
abstention_rate=sum(r['abstained'] for r in results)/len(results),
median_observation_ms=median('observation_ms'),median_policy_ms=median('policy_ms'),
median_execution_ms=median('execution_ms'),
scope='single-step generated browser fixtures, held-out layout templates; not arbitrary websites',
target_vps_validated=False,results=results)
Path(args.output).parent.mkdir(parents=True,exist_ok=True)
Path(args.output).write_text(json.dumps(report,indent=2),encoding='utf-8')
print(json.dumps({k:v for k,v in report.items() if k!='results'},indent=2))
if __name__ == '__main__':
main()