rishanthrajendhran commited on
Commit
79883c6
·
verified ·
1 Parent(s): 3525747

Card: strict '<' flag rule, format-assignment wording, vLLM section; thresholds.json flag rule

Browse files
Files changed (2) hide show
  1. README.md +40 -2
  2. thresholds.json +2 -2
README.md CHANGED
@@ -93,9 +93,46 @@ print(p_human(outline))
93
 
94
  Build the prompt string exactly as above rather than through the chat template.
95
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  ### Thresholds
97
 
98
- IdeaLens-NoParaphrase flags a document as having AI ideas when P(human) is at or below a cut. Each cut is set so
99
  that a given share of human documents is flagged (the false-positive rate, FPR), measured on the 80,000 human
100
  documents in IdeaLens-1M's `calibration` split (10,000 per format). The paper's operating point is the global
101
  cut at 1% FPR. These cuts were fitted on scores from the merged weights in this repo, computed locally in bf16.
@@ -105,7 +142,8 @@ cut at 1% FPR. These cuts were fitted on scores from the merged weights in this
105
  | Global cut | 0.00538 | 0.03359 | 0.09947 | 0.50391 | 0.94738 |
106
 
107
  Per-format cuts give each format its own operating point. They need the document's format, which the paper
108
- assigns with WebOrganizer's FormatClassifier (FormatClassifier-NoURL when there is no URL). Each is the
 
109
  format's own quantile, shrunk toward the global cut with weight n / (n + 2500); at 0.1% FPR 10,000 documents
110
  per format are too few, so there is no per-format cut. A document outside these eight formats has no
111
  per-format cut; do not fall back to the global cut for it.
 
93
 
94
  Build the prompt string exactly as above rather than through the chat template.
95
 
96
+ ### Score with vLLM
97
+
98
+ For many inputs, vLLM is about 15 times faster than the code above and fits much longer inputs on one 80 GB GPU.
99
+ With vLLM 0.21 (install `xgrammar==0.2.1`; later releases require transformers < 5), reusing `SYSTEM`, `SUFFIX`,
100
+ `HUMAN` and `AI` from above:
101
+
102
+ ```python
103
+ import math, os
104
+ os.environ.setdefault("VLLM_USE_FLASHINFER_SAMPLER", "0") # FlashInfer kernels compile CUDA code and need nvcc
105
+ os.environ.setdefault("VLLM_USE_FLASHINFER_MOE_FP16", "0")
106
+ os.environ.setdefault("VLLM_USE_DEEP_GEMM", "0") # H100 warmup crashes when DeepGEMM is not installed
107
+ from transformers import AutoTokenizer
108
+ from vllm import LLM, SamplingParams
109
+
110
+ tok = AutoTokenizer.from_pretrained("rishanthrajendhran/IdeaLens-NoParaphrase")
111
+ llm = LLM(model="rishanthrajendhran/IdeaLens-NoParaphrase", dtype="bfloat16", max_num_seqs=256, enable_prefix_caching=False,
112
+ max_logprobs=20, enable_flashinfer_autotune=False, seed=0)
113
+ sp = SamplingParams(max_tokens=1, temperature=0.0, logprobs=20)
114
+
115
+ def p_human_batch(outlines):
116
+ prompts = [{"prompt_token_ids": tok.encode(f"<|im_start|>system\n{SYSTEM}<|im_end|>\n<|im_start|>user\n{x}{SUFFIX}",
117
+ add_special_tokens=False)} for x in outlines]
118
+ out = []
119
+ for r in llm.generate(prompts, sp, use_tqdm=False):
120
+ lp = r.outputs[0].logprobs[0] # the top 20 next-token log-probabilities
121
+ out.append(1 / (1 + math.exp(lp[AI].logprob - lp[HUMAN].logprob)))
122
+ return out
123
+
124
+ # when done: without this, vLLM 0.21 keeps a script running after its last line
125
+ llm.llm_engine.engine_core.shutdown()
126
+ ```
127
+
128
+ `max_num_seqs=256` keeps every running sequence's Mamba state in memory; vLLM's H100 default (1,024) does not fit
129
+ beside the weights. If `human` or `ai` is missing from the top 20 (rare), score the prompt followed by each label
130
+ token with `SamplingParams(max_tokens=1, prompt_logprobs=0)` and read the last prompt log-probability of each.
131
+ Scores agree with the training-time scores to about 0.001 in P(human) on average; A100 and H100 GPUs differ by as much.
132
+
133
  ### Thresholds
134
 
135
+ IdeaLens-NoParaphrase flags a document as having AI ideas when P(human) is below a cut. Each cut is set so
136
  that a given share of human documents is flagged (the false-positive rate, FPR), measured on the 80,000 human
137
  documents in IdeaLens-1M's `calibration` split (10,000 per format). The paper's operating point is the global
138
  cut at 1% FPR. These cuts were fitted on scores from the merged weights in this repo, computed locally in bf16.
 
142
  | Global cut | 0.00538 | 0.03359 | 0.09947 | 0.50391 | 0.94738 |
143
 
144
  Per-format cuts give each format its own operating point. They need the document's format, which the paper
145
+ assigns with WebOrganizer's annotation prompt run on Gemini 3.7 Flash; the calibration documents use the formats
146
+ recorded in IdeaLens-1M. Each is the
147
  format's own quantile, shrunk toward the global cut with weight n / (n + 2500); at 0.1% FPR 10,000 documents
148
  per format are too few, so there is no per-format cut. A document outside these eight formats has no
149
  per-format cut; do not fall back to the global cut for it.
thresholds.json CHANGED
@@ -1,10 +1,10 @@
1
  {
2
  "model": "rishanthrajendhran/IdeaLens-NoParaphrase",
3
  "input": "outline",
4
- "flag_rule": "flag the document as AI when P(human) <= cut",
5
  "calibration": {
6
  "data": "IdeaLens-1M, calibration split (human documents only)",
7
- "scores_from": "the merged weights released in this repo, scored locally in bf16",
8
  "n_humans": 80000,
9
  "n_per_format": {
10
  "Academic Writing": 10000,
 
1
  {
2
  "model": "rishanthrajendhran/IdeaLens-NoParaphrase",
3
  "input": "outline",
4
+ "flag_rule": "flag the document as AI when P(human) < cut",
5
  "calibration": {
6
  "data": "IdeaLens-1M, calibration split (human documents only)",
7
+ "scores_from": "the merged weights released in the IdeaLens-NoParaphrase repo, scored locally in bf16",
8
  "n_humans": 80000,
9
  "n_per_format": {
10
  "Academic Writing": 10000,