Text Generation
Transformers
Safetensors
English
nemotron_h
ai-text-detection
idea-provenance
conversational
Instructions to use rishanthrajendhran/IdeaLens-NoParaphrase with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use rishanthrajendhran/IdeaLens-NoParaphrase with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="rishanthrajendhran/IdeaLens-NoParaphrase") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# pip install -U transformers accelerate # Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("rishanthrajendhran/IdeaLens-NoParaphrase") model = AutoModelForCausalLM.from_pretrained("rishanthrajendhran/IdeaLens-NoParaphrase", device_map="auto") messages = [ {"role": "user", "content": "Who are you?"}, ] inputs = tokenizer.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=256) print(tokenizer.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use rishanthrajendhran/IdeaLens-NoParaphrase with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "rishanthrajendhran/IdeaLens-NoParaphrase" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "rishanthrajendhran/IdeaLens-NoParaphrase", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/rishanthrajendhran/IdeaLens-NoParaphrase
- SGLang
How to use rishanthrajendhran/IdeaLens-NoParaphrase with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "rishanthrajendhran/IdeaLens-NoParaphrase" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "rishanthrajendhran/IdeaLens-NoParaphrase", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "rishanthrajendhran/IdeaLens-NoParaphrase" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "rishanthrajendhran/IdeaLens-NoParaphrase", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use rishanthrajendhran/IdeaLens-NoParaphrase with Docker Model Runner:
docker model run hf.co/rishanthrajendhran/IdeaLens-NoParaphrase
Card: strict '<' flag rule, format-assignment wording, vLLM section; thresholds.json flag rule
Browse files- README.md +40 -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
|
| 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
|
|
|
|
| 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) <
|
| 5 |
"calibration": {
|
| 6 |
"data": "IdeaLens-1M, calibration split (human documents only)",
|
| 7 |
-
"scores_from": "the merged weights released in
|
| 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,
|