"""Binoculars: pure ratio maths + the never-raise/abstain contract.""" import torch from text_detection.detectors.binoculars import BinocularsDetector, binoculars_score from text_detection.schema import Verdict def test_score_is_finite_float(): torch.manual_seed(0) obs = torch.randn(1, 8, 50) perf = torch.randn(1, 8, 50) labels = torch.randint(0, 50, (1, 8)) s = binoculars_score(obs, perf, labels) assert isinstance(s, float) assert s == s def test_machine_like_text_scores_lower(): # When the observer is very confident on the true tokens (low perplexity) # while cross-perplexity stays moderate, the ratio drops - the machine signal. T, V = 10, 40 labels = torch.randint(0, V, (1, T)) confident_obs = torch.full((1, T, V), -10.0) for t in range(T): confident_obs[0, t, labels[0, t]] = 10.0 unsure_obs = torch.zeros(1, T, V) perf = torch.randn(1, T, V) assert binoculars_score(confident_obs, perf, labels) < binoculars_score(unsure_obs, perf, labels) async def test_empty_text_returns_error_result(): det = BinocularsDetector() res = await det.detect_text("") assert res.error is not None assert res.confidence == 0.0 async def test_short_text_abstains_without_loading_models(): det = BinocularsDetector() res = await det.detect_text("only five words here now") assert res.detector == "text_binoculars" assert res.verdict == Verdict.UNCERTAIN assert res.confidence == 0.0 assert res.error is None