From Tokens to Files: Multi-Granularity Detection and Localization of AI-Involved Code
Organizations: Peking University · Baidu Inc.
Abstract
The increasing use of large language models for code generation calls for methods that distinguish purely human-written code from AI-involved code: files in which any part, however small, was generated or substantially modified by a model. Beyond flagging such files, we aim to localize the lines or blocks attributable to AI. Existing approaches compress a file into a single score, from surface stylistic features or a global code representation, which averages away the evidence when only a few blocks are AI-involved. We propose a framework that models AI authorship at the token level and predicts at the line, block, and file levels. A frozen code language model is equipped with two low-rank adapters, trained separately on machine-written and human-written files; their per-token log-likelihood ratio provides local evidence of AI authorship. Lightweight heads aggregate this evidence within lines and blocks, using the surrounding code context, and their local predictions are aggregated into a file-level decision. We train on mixed-authorship files built from human originals and their AI-generated or AI-modified counterparts, including continuation and fill-in-the-middle scenarios. On an internal test set of 11,773 AI-involved files across six generation regimes against 2,541 human files, our method reaches 72.4 macro F1 at a 1% FPR operating point. With no adaptation, it reaches 62.5 line-level F1 on HybridCodeAuthorship, an external human-AI co-writing benchmark with no training split, above the 56 its own paper reports as the best line-level result. On 19,445 human-written files from repositories created before 2022, the false-positive rate stays between 0.55% and 0.81% under the transported 1% threshold, so the operating point holds on real human code.
Figures & tables
| Method | base | unseen | rewrite | compl. | refac. | fim | Avg. | |
|---|---|---|---|---|---|---|---|---|
| macro F1 (%) at the FPR operating point | AUROC / TPR@1%FPR / F1 | |||||||
| A | log-rank | / / | ||||||
| LRR | / / | |||||||
| Fast-DetectGPT | / / | |||||||
| Binoculars | / / | |||||||
| DetectCodeGPT | / / | |||||||
| All cells | Mixed cells | TPR@1%FPR | ||||
| Variant | AUROC | AUROC | % | |||
| Token-level panel ; reference: , file mean | ||||||
| , file mean (ref.) | 0.838 | – | 0.707 | – | 47.1 | – |
| only | 0.773 | [ , ] | 0.646 | [ , ] | 18.9 | [ , ] |
| only | 0.506 | [ , ] | 0.497 | [ , ] | 1.0 | [ , ] |
| no ratio (AI-side NLL) | 0.522 | [ , ] | 0.563 | [ , ] | 0.5 | [ , ] |
| Method | AICD-Bench T1 | AICD-Bench T3 | DroidCollection | ||||
|---|---|---|---|---|---|---|---|
| P1 | P2 | P1 | P2 | P1 | P2 | ||
| AUROC / TPR@1%FPR / macro F1 (%) | |||||||
| A | DetectCodeGPT | 0.703 / 6.5 / 49.7 | – | 0.666 / 0.2 / 40.2 | – | 0.669 / 3.0 / 35.1 | – |
| B | CodeT5+ + MLP | 0.471 / 1.3 / 44.8 | 0.629 / 11.6 / 53.5 | 0.462 / 0.7 / 40.7 | 0.927 / 43.3 / 73.5 | 0.521 / 0.8 / 32.7 | 0.982 / 81.5 / 89.7 |
| CodeBERT | 0.467 / 1.5 / 44.9 | 0.651 / 17.0 / 58.5 | 0.356 / 0.6 / 40.6 | 0.921 / 49.1 / 76.7 | 0.469 / 1.0 / 47.2 | 0.988 / 87.8 / 94.7 | |
| UniXcoder | 0.489 / 1.9 / 45.3 | 0.618 / 12.6 / 55.0 | 0.374 / 0.7 / 40.7 | 0.929 / 35.8 / 68.9 | 0.499 / 1.5 / 50.8 | 0.991 / 90.1 / 96.2 | |
| Method | HCA, P1 (zero adaptation) | ||||
|---|---|---|---|---|---|
| Line | Block | Block | File | ||
| AUROC / TPR@1%FPR / F1 (%) | |||||
| A | Fast-DetectGPT | 0.495 / 1.2 / 2.2 | 0.568 / 1.8 / 3.5 | 0.568 / 1.9 / 3.7 | 0.499 / 0.0 / 0.0 |
| AIGCode Detector | 0.646 / 1.4 / 2.7 | 0.513 / 2.2 / 4.1 | 0.501 / 1.7 / 3.2 | 0.496 / 1.4 / 16.7 | |
| B | CodeBERT | 0.666 / 6.1 / 11.4 | 0.577 / 4.8 / 9.0 | 0.589 / 5.4 / 10.1 | 0.594 / 3.3 / 6.3 |
| UniXcoder | 0.581 / 3.6 / 6.8 | 0.562 / 4.8 / 9.0 | 0.570 / 5.2 / 9.8 | 0.580 / 2.4 / 4.6 | |
Appendix figures & tables21 assets
Supplementary material from the paper’s appendix.
Appendix
| Appendix | Contents | Main text |
|---|---|---|
| A.1 Extended related work | zero-shot likelihood statistics, supervised code detectors, two-model contrasts, spans and boundaries in text, mixed and fine-grained authorship resources | 1 |
| A.2 Accuracy and F1 at the transported threshold | why neither metric appears in the main text; accuracy per test cell and per synthesis form against the degenerate baseline | 4.4 |
| A.3 Block-level metrics | block and line metrics of both heads, per test cell, at both | 5.2 |
| A.4 Localization diagnostics | localization value by AI segment length and by AI ratio | 5.2 |
| A.5 Additional ablations | feature families per cell, the aggregation sweep, the line-head read-out, the block-supervision corpus, syntax-aligned blocks, the backbone swap | 3.2 , 3.3 , 5.3 |
| A.6 Formatting controls | whitespace and length ceilings; the two levels of formatting normalization | 5.4 |
| Read-out | threshold | base | unseen | rewrite | compl. | refac. | fim | human |
|---|---|---|---|---|---|---|---|---|
| Token ratio, file mean | 0.897 | 0.896 | 0.893 | 0.263 | 0.506 | 0.127 | 0.949 | |
| + block head, | 0.844 | 0.911 | 0.804 | 0.490 | 0.527 | 0.275 | 0.923 | |
| + block head, | 0.846 | 0.909 | 0.803 | 0.422 | 0.487 | 0.212 | 0.943 | |
| all-pos. floor | – | 1.000 | 1.000 | 1.000 | 1.000 | 1.000 | 1.000 | 0.000 |
| Cell | blocks | pos | AUROC | recall | |
|---|---|---|---|---|---|
| , development threshold | |||||
| base | 31,369 | 1.000 | – | 89.6 | 81.2 |
| unseen | 35,225 | 1.000 | – | 92.9 | 86.7 |
| rewrite | 23,777 | 1.000 | – | 86.6 | 76.4 |
| compl. | 19,131 | 0.570 | 0.912 | 80.0 | 71.3 |
| refac. | 22,010 | 0.655 | 0.648 | 62.6 | 53.0 |
| AI-line | Line | Line | Line | |||
|---|---|---|---|---|---|---|
| Cell | files | lines | rate | AUROC | recall | |
| base | 2,541 | 237,027 | 1.000 | – | 91.2 | 83.8 |
| unseen | 2,541 | 267,667 | 1.000 | – | 93.4 | 87.6 |
| rewrite | 1,996 | 178,961 | 1.000 | – | 86.2 | 75.7 |
| compl. | 1,496 | 143,999 | 0.519 | 0.927 | 85.2 | 90.7 |
| refac. | 1,899 | 165,466 | 0.334 | 0.599 | 48.0 | 61.2 |
| Variant | 5–9 | 10–24 | All | ||
|---|---|---|---|---|---|
| #positive files | 439 | 449 | 756 | 1,152 | 2,796 |
| Token-level aggregation | |||||
| Token ratio, file | 0.510 | 0.561 | 0.630 | 0.775 | 0.660 |
| Token ratio, oracle | 0.650 | 0.738 | 0.840 | 0.920 | 0.827 |
| Token ratio, oracle-pair | 0.560 | 0.654 | 0.771 | 0.888 | 0.758 |
| Length-only probe | 0.453 | 0.497 | 0.543 | 0.680 | 0.578 |
| Method | – | – | – | All | ||
|---|---|---|---|---|---|---|
| #positive files | 1,298 | 1,105 | 914 | 801 | 577 | 4,695 |
| all-negative macro F1 | 39.8 | 41.1 | 42.4 | 43.2 | 44.9 | 26.0 |
| Token ratio, file mean | 0.642/11.2/50.4 | 0.702/17.8/57.0 | 0.716/17.6/57.9 | 0.778/23.3/62.8 | 0.858/27.0/66.5 | 0.720/18.0/43.5 |
| + block head, | 0.664 /11.3/50.5 | 0.731 /18.6/57.6 | 0.796/22.3/61.4 | 0.858 /35.0/70.4 | 0.909 /48.0/78.4 | 0.769 /23.7/48.2 |
| + block head, | 0.653/12.1/51.2 | 0.727/19.9/58.6 | 0.786/20.4/60.0 | 0.842/32.0/68.5 | 0.901/43.2/75.9 | 0.759/22.7/47.4 |
| + line head, file mean | 0.646/8.3/47.8 | 0.713/12.6/52.7 | 0.799 /14.9/55.7 | 0.843/23.1/62.6 | 0.900/38.3/73.3 | 0.756/16.8/42.4 |
| base | unseen | rewrite | compl. | refac. | fim | |
|---|---|---|---|---|---|---|
| Block head (AUROC) | 0.954 | 0.974 | 0.944 | 0.789 | 0.819 | 0.638 |
| no raw family | ||||||
| no -score family | ||||||
| no positional family | ||||||
| no language family |
| All cells | Mixed cells | TPR@1%FPR | ||||
| Aggregation | AUROC | AUROC | % | |||
| Block head , | ||||||
| logit mean (ref.) | 0.853 | – | 0.749 | – | 48.4 | – |
| mean | 0.853 | [ , ] | 0.752 | [ , ] | 47.9 | [ , ] |
| top- mean | 0.850 | [ , ] | 0.754 | [ , ] | 45.2 | [ , ] |
| top- mean | 0.849 | [ , ] | 0.753 | [ , ] | 44.2 | [ , ] |
| All cells | Mixed cells | TPR@1%FPR | ||||
| Read-out | AUROC | AUROC | % | |||
| Panel 1 : line head of Table 1 | ||||||
| line mean (ref.) | 0.836 | – | 0.751 | – | 37.4 | – |
| line max | 0.832 | [ , ] | 0.756 | [ , ] | 37.4 | [ , ] |
| block head | 0.853 | [ , ] | 0.749 | [ , ] | 48.4 | [ , ] |
| Panel 2 : retrained line head, positional encoding on | ||||||
| Training corpus | All cells | Mixed | TPR@1% | ||||
|---|---|---|---|---|---|---|---|
| Corpus | files | pure blocks | dev | AUROC | AUROC | % | |
| full corpus (ref.) | 3,164 | 17,767 | 0.914 | 0.853 | – | 0.749 | 48.4 |
| continuation only | 1,686 | 11,111 | 0.818 | 0.730 | [ , ] | 0.620 | 8.8 |
| fill-in-middle only | 1,478 | 6,656 | 0.620 | 0.583 | [ , ] | 0.492 | 1.6 |
| corpus halved | 1,582 | 8,637 | 0.754 | 0.686 | [ , ] | 0.556 | 10.1 |
| corpus | 1,994 | 10,807 | 0.768 | 0.683 | [ , ] | 0.558 | 8.0 |
| Partition | pure-AI % | pure-human % | mixed % | AI lines captured % | diluted % |
|---|---|---|---|---|---|
| compl. ( ) | |||||
| 50.1 | 43.0 | 6.9 | 92.3 | 6.5 | |
| 48.5 | 37.2 | 14.3 | 82.4 | 13.4 | |
| AST | 51.8 | 36.6 | 11.6 | 11.8 | 50.8 |
| AST+K8 gaps | 49.7 | 44.1 | 6.2 | 90.5 | 18.3 |
| refac. ( ) | |||||
| Static probe (ceiling) | Detector, formatting erased | |||||
|---|---|---|---|---|---|---|
| Cell | Whitespace only | Length only | Original | Soft | Hard | (Hard Orig.) |
| base | 0.650 | 0.553 | 0.964 | 0.958 | 0.925 | |
| unseen | 0.643 | 0.561 | 0.968 | 0.962 | 0.941 | |
| rewrite | 0.666 | 0.564 | 0.972 | 0.963 | 0.914 | |
| compl. | 0.539 | 0.603 | 0.711 | 0.699 | 0.675 | |
| refac. | 0.600 | 0.539 | 0.810 | 0.789 | 0.741 | |
| Language | Token ratio | Block | Block | Line head | |
|---|---|---|---|---|---|
| JavaScript | 4,545 | 0.86 | 0.84 | 0.68 | 1.67 |
| Java | 3,173 | 0.28 | 0.44 | 0.28 | 0.35 |
| Python | 3,038 | 0.33 | 0.30 | 0.13 | 0.39 |
| C | 1,721 | 0.41 | 1.51 | 2.21 | 0.58 |
| C# | 1,190 | 0.76 | 1.60 | 0.17 | 0.67 |
| PHP | 1,125 | 1.42 | 0.44 | 0.00 | 0.71 |
| Read-out | threshold | synthetic | all | Python | Java | JavaScript | TypeScript | Go |
| FPR operating point (deployment) | ||||||||
| Token ratio, file mean | 0.67 | 0.60 | 0.33 | 0.28 | 0.86 | 0.38 | 0.16 | |
| + block head, | 0.63 | 0.72 | 0.30 | 0.44 | 0.84 | 0.13 | 0.98 | |
| + block head, | 0.35 | 0.55 | 0.13 | 0.28 | 0.68 | 0.00 | 0.49 | |
| + line head, file mean | 0.87 | 0.81 | 0.39 | 0.35 | 1.67 | 0.88 | 0.65 | |
| Accuracy-maximising threshold (reported for completeness) | ||||||||
| Read-out | threshold | FPR (%) | |
|---|---|---|---|
| Block head, (blocks) | 259,682 | 9.90 | |
| Block head, (blocks) | 134,703 | 8.89 | |
| Line head (lines) | 1,955,822 | 17.33 |
| Split | Content | #files | Used for |
|---|---|---|---|
| train / part1 | pure human/AI pairs | 12,002 | the two LoRA adapters |
| train / part2 | mixed files + their human originals | 3,164 | the block head |
| dev / mixed | mixed files | 398 | , head hyper-parameters |
| dev / pure | pure human/AI pairs | 4,062 | aggregation and threshold |
| test | 6 generation cells + shared human pool | 14,314 | reporting only |
| Family | Columns | # |
| Block head | ||
| raw | : mean, sd, min, max, , positive rate | 10 |
| , , : mean, sd, | 9 | |
| : mean, ; -rank and top-1 rate: mean | 4 | |
| for the base, AI and human passes: mean | 3 | |
| raw.size | token count, line coverage, tokens and characters per line, block lines | 5 |
| Method | base | unseen | rewrite | compl. | refac. | fim | Avg. | |
|---|---|---|---|---|---|---|---|---|
| each cell, top bottom: AUROC / TPR@1%FPR / macro F1 (%) | ||||||||
| A | log-rank | 0.415 0.2 33.3 | 0.416 0.1 33.2 | 0.441 0.1 35.7 | 0.584 0.7 39.1 | 0.507 0.3 36.5 | 0.566 1.3 40.9 | 0.488 0.4 36.5 |
| LRR | 0.401 0.2 33.4 | 0.415 0.1 33.2 | 0.430 0.1 35.7 | 0.569 0.5 38.9 | 0.491 0.2 36.4 | 0.577 0.7 40.3 | 0.481 0.3 36.3 | |
| Fast-DetectGPT | 0.376 0.2 33.3 | 0.397 0.2 33.3 | 0.365 0.2 35.9 | 0.685 3.3 41.8 | 0.500 0.4 36.6 | 0.566 0.5 40.1 | 0.481 0.8 36.8 | |
| Binoculars | 0.434 0.1 33.2 | 0.433 0.1 33.2 | 0.431 0.1 35.7 | 0.595 0.7 39.1 | 0.502 0.5 36.7 | 0.532 0.8 40.4 | 0.488 0.4 36.4 | |
| DetectCodeGPT | 0.466 0.2 33.3 | 0.477 0.0 33.1 | 0.486 0.0 35.7 | 0.583 0.7 39.1 | 0.530 0.3 36.5 | 0.569 1.0 40.6 | 0.518 0.4 36.4 | |
| Benchmark | Granularity | Native label | #eval (neg.) | Train split | Published (metric) |
|---|---|---|---|---|---|
| AICD-Bench T1 | file | binary | 20,000 (15,519) | yes | 62.31 (macro-F1, zs-LLM) |
| AICD-Bench T3 | file | 4-class | 20,000 (13,447) | yes | 61.65 (macro-F1, FT) |
| DroidCollection | file | 4-class | 105,826 (49,932) | yes | 97.00 (domain-avg wF1, 2-cls, FT) |
| HCA | line, chunk | per-line binary | 10,488 (1,904) | no | 56.0 (F1, line, zs) |
| Method | AICD-Bench T1 | AICD-Bench T3 | DroidCollection |
|---|---|---|---|
| LogRank | 0.665 / 5.5 / 48.8 | 0.626 / 0.0 / 40.0 | 0.626 / 3.3 / 35.4 |
| LRR | 0.663 / 2.9 / 46.3 | 0.656 / 1.3 / 41.4 | 0.628 / 2.0 / 34.0 |
| Fast-DetectGPT | 0.637 / 10.4 / 53.2 | 0.653 / 6.1 / 46.1 | 0.604 / 6.5 / 38.6 |
| Binoculars | 0.529 / 1.0 / 44.5 | 0.406 / 0.0 / 40.0 | 0.497 / 0.4 / 32.3 |
| DetectCodeGPT | 0.703 / 6.5 / 49.7 | 0.666 / 0.2 / 40.2 | 0.669 / 3.0 / 35.1 |
| AIGCode Detector | 0.505 / 1.8 / 45.2 | 0.438 / 1.1 / 40.7 | 0.510 / 2.7 / 34.8 |
| Method | HCA, P1 (zero adaptation) | ||||
|---|---|---|---|---|---|
| Line | Block | Block | File | ||
| AUROC / TPR@1%FPR / F1 (%) | |||||
| A | LogRank | 0.509 / 0.6 / 1.1 | 0.592 / 0.3 / 0.6 | 0.587 / 0.3 / 0.6 | 0.007 / 0.0 / 0.0 |
| LRR | 0.491 / 0.3 / 0.6 | 0.583 / 1.2 / 2.3 | 0.581 / 1.3 / 2.5 | 0.050 / 1.1 / 2.2 | |
| Fast-DetectGPT | 0.495 / 1.2 / 2.2 | 0.568 / 1.8 / 3.5 | 0.568 / 1.9 / 3.7 | 0.499 / 0.0 / 0.0 | |
| Binoculars | 0.474 / 0.3 / 0.6 | 0.538 / 0.2 / 0.4 | 0.523 / 0.2 / 0.3 | 0.149 / 0.0 / 0.0 | |
Authorship Attribution
Authorship attribution identifies or verifies who wrote a text, code sample, or other creative work from patterns in its style and content.
See all 66 papers