Instructions to use rishanthrajendhran/IdeaLens with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use rishanthrajendhran/IdeaLens with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="rishanthrajendhran/IdeaLens") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("rishanthrajendhran/IdeaLens") model = AutoModelForCausalLM.from_pretrained("rishanthrajendhran/IdeaLens", 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=40) print(tokenizer.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use rishanthrajendhran/IdeaLens with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "rishanthrajendhran/IdeaLens" # 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", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/rishanthrajendhran/IdeaLens
- SGLang
How to use rishanthrajendhran/IdeaLens 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" \ --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", "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" \ --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", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use rishanthrajendhran/IdeaLens with Docker Model Runner:
docker model run hf.co/rishanthrajendhran/IdeaLens
You need to agree to share your contact information to access this model
This repository is publicly accessible, but you have to accept the conditions to access its files and content.
Access is granted individually. Please say who you are and what you intend to use the weights for.
Log in or Sign Up to review the conditions and access this model content.
IdeaLens
IdeaLens detects who came up with the ideas in a document, rather than who wrote its words. It reads a role-labelled outline of the document (an ordered list of items, each giving one idea and the discourse role it plays, such as Central Development or Open Question) and returns P(human), the probability that the ideas are human.
IdeaLens is nvidia/NVIDIA-Nemotron-3.5-Lightning-30B-A3B-BF16 fine-tuned with LoRA (rank 64) on the outlines of 1M
English web documents (IdeaLens-1M). The training
outlines were paraphrased to remove the documents' wording, so the model has to fit its labels through the ideas.
Results
From the paper:
- IdeaLens is accurate both when a document's ideas and words come from the same source (95.3%) and when they come from different sources (81.3%). ProseLens, trained identically on the raw text, reaches 99.1% and 25.4%; Pangram 4 reaches 98.5% and 25.9%.
- As models write from increasingly detailed human plans, IdeaLens's AI flag rate falls from 95% to 7%, while Pangram 4 still flags 92%. From AI-derived plans, IdeaLens stays above 96%.
- On TwiceTold, 50 stories that human authors wrote from AI-generated plans, IdeaLens flags 68% as AI, against 8% for Pangram 4.
- On 19 existing detection benchmarks, IdeaLens keeps strong detection rates at low false-positive rates across domains, formats and languages.
Usage
Scoring a document takes two steps:
- Extract an outline. An LLM writes the outline from the document, its format's role vocabulary and six worked examples (the paper uses Gemini 3.7 Flash). The prompts and role vocabularies are in the code repository: link added on publication. Score the outline as extracted; the paraphrasing step is only for training data.
- Score the outline with this model, as below.
Load the merged model (66 GB download)
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
tok = AutoTokenizer.from_pretrained("rishanthrajendhran/IdeaLens")
model = AutoModelForCausalLM.from_pretrained("rishanthrajendhran/IdeaLens", dtype=torch.bfloat16, device_map="auto").eval()
The weights take 59 GiB of GPU memory, and each input adds more; see Hardware requirements.
Or apply the adapter to the base model (3 GB download)
adapter/ holds the LoRA adapter as trained, in the layout of the Tinker training service. If you already have the
base model, load_adapter.py merges the adapter into it in memory. The resulting weights are bit-identical to the
merged model's:
import importlib.util
from huggingface_hub import hf_hub_download
path = hf_hub_download("rishanthrajendhran/IdeaLens", "load_adapter.py")
spec = importlib.util.spec_from_file_location("load_adapter", path)
la = importlib.util.module_from_spec(spec); spec.loader.exec_module(la)
model, tok = la.load_model() # base model + adapter/, then la.p_human(model, tok, outline)
Do not load adapter/ with peft.PeftModel. In transformers, Nemotron fuses the Mamba gate and x projections into
one in_proj and stores each layer's 128 routed experts as a single 3D tensor, so PEFT has nowhere to attach most of
the adapter and skips it without a warning; the model then scores close to the base model. tinker-cookbook's
weights.build_hf_model can also merge the adapter into full weights.
Score an outline
Write the outline one item per line, as [Role] content. IdeaLens compares the next-token probabilities of human and ai:
SYSTEM = "Given a role-labelled outline of a document, answer with one word: human if the source document was human-written, ai if it was AI-generated."
SUFFIX = "<|im_end|>\n<|im_start|>assistant\n<think>\n\n</think>\n\n"
HUMAN, AI = 50755, 2464 # token ids of "human" and "ai"
@torch.no_grad()
def p_human(outline):
ids = tok.encode(f"<|im_start|>system\n{SYSTEM}<|im_end|>\n<|im_start|>user\n{outline}{SUFFIX}",
add_special_tokens=False)
logits = model(torch.tensor([ids], device=model.device)).logits[0, -1].float()
return torch.softmax(logits[[HUMAN, AI]], -1)[0].item()
outline = ("[Central Development] A town's water supply fails after a drought, and residents organise to share wells.\n"
"[Background Context] The reservoir has been shrinking for three summers.\n"
"[Open Question] Whether the council will fund a new pipeline remains undecided.")
print(p_human(outline))
Build the prompt string exactly as above rather than through the chat template.
Thresholds
IdeaLens flags a document as having AI ideas when P(human) is at or below a cut. Each cut is set so
that a given share of human documents is flagged (the false-positive rate, FPR), measured on the 80,000 human
documents in IdeaLens-1M's calibration split (10,000 per format). The paper's operating point is the global
cut at 1% FPR.
| FPR | 0.1% | 0.5% | 1% | 2% | 5% | 10% | 20% |
|---|---|---|---|---|---|---|---|
| Global cut | 0.01691 | 0.07279 | 0.13712 | 0.34047 | 0.72713 | 0.89798 | 0.97156 |
Per-format cuts give each format its own operating point. They need the document's format, which the paper assigns with WebOrganizer's FormatClassifier (FormatClassifier-NoURL when there is no URL). Each is the format's own quantile, shrunk toward the global cut with weight n / (n + 2500); at 0.1% FPR 10,000 documents per format are too few, so there is no per-format cut. A document outside these eight formats has no per-format cut; do not fall back to the global cut for it.
| Format | 0.5% | 1% | 2% | 5% | 10% | 20% |
|---|---|---|---|---|---|---|
| Nonfiction Writing | 0.05358 | 0.08989 | 0.17022 | 0.54060 | 0.86724 | 0.96940 |
| Knowledge Article | 0.06944 | 0.10700 | 0.20819 | 0.61170 | 0.88568 | 0.97190 |
| Personal Blog | 0.09460 | 0.25214 | 0.50599 | 0.78596 | 0.90989 | 0.97157 |
| News Article | 0.04970 | 0.09170 | 0.23610 | 0.57516 | 0.81288 | 0.94887 |
| Academic Writing | 0.16045 | 0.37109 | 0.63082 | 0.87285 | 0.95310 | 0.98617 |
| User Reviews | 0.08956 | 0.24748 | 0.46654 | 0.79774 | 0.93054 | 0.97995 |
| Personal About Page | 0.08280 | 0.17824 | 0.39823 | 0.71519 | 0.87589 | 0.95970 |
| Creative Writing | 0.20831 | 0.35315 | 0.54943 | 0.79025 | 0.90777 | 0.96932 |
thresholds.json holds every cut at full precision, plus per-topic cuts for the WebOrganizer topics with enough calibration documents.
These rates hold for English web documents like the training data. For another domain, fit the cut on human documents from that domain.
Hardware requirements
Measured with transformers 5.15 in bf16 on NVIDIA H100 80GB GPUs (our other runs used A100 80GB), with transformers' PyTorch implementation of the Mamba layers (no fused Mamba kernels installed). We have not tried CPU-only inference.
| Merged model | Adapter route (load_adapter.py) |
|
|---|---|---|
| Download | 65.8 GB | 65.8 GB base model + 3.1 GB adapter |
| Peak CPU RAM while loading | 60 GiB | 60 GiB |
| GPU memory once loaded | 58.8 GiB | 58.8 GiB (66 GiB during the ~10 s it takes to apply the adapter) |
GPU memory then grows with the length of the input, by about 4.2 MiB per token at typical lengths, scoring one input at a time:
| Input tokens | 500 | 1,000 | 2,000 | 4,000 | 8,000 |
|---|---|---|---|---|---|
| Peak GPU memory, one 80 GB GPU | 61.0 GiB | 63.1 GiB | 67.3 GiB | 75.7 GiB | does not fit |
Peak memory per GPU, two 80 GB GPUs (device_map="auto") |
47.4 GiB | 63.7 GiB | |||
| Seconds per input, H100 | 0.18 | 0.34 | 0.66 | 1.32 | 2.70 |
Inputs of 6,000 tokens do not fit on one 80 GB GPU and 12,000 do not fit on two; lowering the Mamba chunk size from 128 to 64 did not change either limit.
IdeaLens reads outlines, which are short. The outlines in IdeaLens-1M's calibration split average about 640 tokens with the prompt, and the longest is under 3,800, so one 80 GB GPU (A100 80GB or H100 80GB) is enough. Outline extraction runs through an LLM API and needs no local GPU.
Intended use and limitations
- IdeaLens estimates the provenance of a document's ideas. It should not be the sole basis for decisions about a person's work.
- It was trained on English web documents of at least 500 words in eight long-form formats (Nonfiction Writing, Knowledge Article, Personal Blog, News Article, Academic Writing, User Reviews, Personal About Page, Creative Writing).
- Its training labels come from the Pangram prose detector, applied to whole documents. They record who wrote the prose; the model learns idea provenance from them only through outlines.
- Errors in outline extraction carry into the score.
Related models
| Model | Backbone | Reads |
|---|---|---|
| IdeaLens (this model) | Nemotron-3.5-Lightning-30B-A3B, LoRA | outline |
| ProseLens | Nemotron-3.5-Lightning-30B-A3B, LoRA | document text |
| IdeaLens-NoParaphrase | Nemotron-3.5-Lightning-30B-A3B, LoRA | outline, trained without paraphrasing |
| IdeaLens-Qwen3.5-9B | Qwen3.5-9B, classification head | outline |
| IdeaLens-ModernBERT-L | ModernBERT-large | outline |
| ProseLens-ModernBERT-L | ModernBERT-large | document text |
| IdeaLens-LogisticClassifier | logistic regression over text-embedding-3-large | outline |
| IdeaLens-ModernBERT-L-NoParaphrase | ModernBERT-large | outline, trained without paraphrasing |
| IdeaLens-ModernBERT-L-RolesOnly | ModernBERT-large | role labels only |
| IdeaLens-Qwen3.5-9B-PerItem | Qwen3.5-9B, classification head | single outline items, pooled |
| IdeaLens-ModernBERT-L-PerItem | ModernBERT-large | single outline items, pooled |
| IdeaLens-LogisticClassifier-PerItem | logistic regression over text-embedding-3-large | single outline items, pooled |
Training data: IdeaLens-1M.
License
OpenMDW-1.1, the license of the base model (see LICENSE).
Citation
@article{idealens2026,
title = {IdeaLens: Detecting AI Ideas in Long-form Writing},
author = {Anonymous},
journal = {arXiv preprint arXiv:TBD},
year = {2026},
url = {https://arxiv.org/abs/TBD}
}
- Downloads last month
- 10
# Gated model: Login with a HF token with gated access permission hf auth login