메뉴
HN
Hacker News 12일 전

고전적 머신러닝으로 LLM 생성 텍스트 판별하기

IMP
7/10
핵심 요약

2026년 초 현재, 주류 LLM이 생성한 텍스트는 강력한 통계적 패턴을 띠고 있어 고전적인 머신러닝 모델로 인간이 쓴 글과 효과적으로 구분할 수 있습니다. 개발자는 Scikit-learn의 기본 모델들을 활용해 단일 문장 기준 약 85%의 정확도를 보이는 AI 텍스트 탐지 데모를 구축했습니다. 이는 기업이나 플랫폼에서 무거운 LLM 모델을 사용하지 않고도 가벼운 분류 모델로 AI 표절을 방지하고 콘텐츠 품질을 관리할 수 있는 실질적인 방안을 제시합니다.

번역된 본문

이 기사는 현재 실험적인 기계 번역이며 오류가 포함되어 있을 수 있습니다. 내용이 명확하지 않다면 원어인 중국어 버전을 참조해 주세요. 번역 품질 개선을 위해 계속 노력하고 있습니다.

요약(TL;DR) 및 데모 2026년 초 기준, 주류 대형 언어 모델(LLM)이 생성한 텍스트는 강력한 통계적 패턴을 띠며, 이는 전통적인 머신러닝(Classical Machine Learning) 모델을 사용해 인간이 작성한 콘텐츠와 효과적으로 구분해 낼 수 있습니다. 이른바 'AI 표절 검사기'들이 실제로 이러한 방식으로 작동할 것이라고 의심됩니다.

온라인 데모: https://lyc8503.github.io/AITextDetector/

이 데모에 사용된 모델은 범용 데이터로 학습되지 않았고 엄격한 최적화나 반복 테스트를 거치지 않았습니다. 테스트 셋 기준 단일 문장 탐지 정확도는 약 85%입니다. 사용하기 전에 잠재적인 한계를 이해하기 위해 본 문서를 끝까지 읽어보시기 바랍니다. 핵심 코드(초안)와 학습된 모델 파일은 GitHub(lyc8503/AITextDetector)에서 확인할 수 있습니다.

배경 (일명 쓸모없는 넋두리) 반 년 전 학교에서 논문을 쓰고 있을 때만 해도, 논문에 대해 AIGC(AI 생성 콘텐츠) 검사를 한다는 소문이 돌고 있었습니다. 저는 CNKI(중국지왕), 왕팡(Wanfang), 그리고 일부 타사 AIGC 탐지 서비스 등 여러 플랫폼을 테스트해 보았고, 이들이 제가 직접 쓴 텍스트와 LLM이 생성한 텍스트를 상당한 정확도로 구분해 낸다는 것을 발견했습니다. 이는 AIGC 탐지가 실제로 어떻게 작동하는지(그리고 이를 어떻게 우회할 수 있는지)에 대한 호기심을 자극했습니다. 하지만 당시에는 라디오, 마인크래프트, 동방 프로젝트 등 신경 쓸 일이 너무 많았고, 몇 번의 실패 끝에 이 생각을 접어두었습니다. 결국 적당히 논문을 마무리하고 일상으로 돌아갔죠.

하지만 최근 로프터(Lofter)를 둘러보다가, 특정 태그 전체가 저품질의 캐릭터성을 완전히 잃어버린 AI 생성 팬픽션으로 넘쳐나는 것을 보게 되었습니다. 제가 어떻게 단숨에 그것들이 AI가 쓴 글임을 알 수 있었을까요? 글쓴이 중 일부는 글을 게시하기 전에 마크다운(Markdown) 형식이나 AI가 생성한 섹션 제목을 정리하는 귀찮은 작업조차 하지 않고, 글의 절반을 유료 결제 뒤에 숨겨버리기 때문입니다 😓. 하지만 대부분의 AI 생성 텍스트는 발견하기 더 어렵습니다. 다양한 글쓰기 슐과 프롬프트에 묻혀 있어 눈에 띄지 않기 때문이죠. 무언가 이상하다고 느낄 때면 이미 늦었습니다. 일부 텍스트는 AI가 쓴 것임을 증명하는 것이 거의 불가능해 편집증적인 의심을 품게 만듭니다. 결국 쓰레기 같은 AI 생성 글을 너무 많이 삼킨 후 더는 참을 수 없어졌습니다. 로프터 탐색은 여기서 중단하고, VS Code를 켤 시간입니다! 네, 이런 연유로 주말 프로젝트였던 'AI 생성 텍스트 탐지기' 제작 아이디어를 부활시키게 되었습니다...

연구 시도 – 실패 현재 인터넷에서 AIGC 탐지를 검색하면 거의 모든 것이 광고로 오염되어 있습니다. 모든 검색 결과가 에세이 AI 재작성 서비스뿐입니다. 당시 저는 그 소음 속을 뒤져 '텍스트 퍼플렉시티(Text perplexity, 혼란도)'라는 개념을 찾았습니다. 개념은 간단합니다. 기존 LLM을 사용하여 주어진 문장에서 각 단어가 나타날 확률을 추정하는 것입니다. 거의 모든 단어가 LLM의 예측(Top-N)에서 높은 순위를 차지한다면, 그 문장은 AI가 생성했을 확률이 높습니다. 반대로 예측을 벗어나는 예상치 못한 단어들이 많다면 인간이 작성했을 가능성이 높습니다. 꽤 유망해 보이죠? 저는 이 방법을 시도해 보느라 약간의 시간을 보냈지만, 결과는 실망스러웠습니다. 오탐지와 미탐지가 너무 많았고, 합리적인 임계값을 설정할 수도 없었습니다. 게다가 추론 비용이 높고, 교차 모델 일반화(Cross-model generalization)가 어려우며, 로컬에 대형 모델을 배포하기 까다롭고, 비공개 가중치(Closed-weight) 모델은 통합하기 어렵다는 실질적인 문제도 있었습니다. 전반적으로 이 접근 방식은 우아하지도 않고 신뢰할 수도 없었습니다. 광고성 '튜토리얼'에 속은 실패한 시도였습니다.

어느 정도 성공한 시도 – scikit-learn SVM 온라인 자료가 쓸모없었기 때문에, 다시 올드스쿨 연금술로 돌아갔습니다. scikit-learn, 실행! scikit-learn의 로드맵(Roadmap)에 따라 분류 작업을 위한 좋은 시작점으로 선형 SVM(Linear SVC)과 나이브 베이즈(Naive Bayes)를 직접 선택했습니다. (속삭임: 이것은 저의 직관과도 일치했습니다. LLM은 분명히 단어 선택의 패턴을 가지고 있으며, 심지어 나이브 베이즈 분류기조차 이를 잡아낼 수 있을 것이라고요. 다만 그 신호가 이렇게까지 강할 줄은 몰랐습니다.)

데이터 생성 올드스쿨 연금술의 전통...

원문 보기
원문 보기 (영어)
This article is currently an experimental machine translation and may contain errors. If anything is unclear, please refer to the original Chinese version. I am continuously working to improve the translation. TL;DR & Demo As of early 2026, mainstream LLM-generated text exhibits strong statistical patterns that can be effectively distinguished from human-written content using traditional machine learning models. I suspect this is how many so-called “AI plagiarism checkers” actually work under the hood. Online Demo: https://lyc8503.github.io/AITextDetector/ The model used in this demo is not trained on general-purpose data , nor has it undergone rigorous optimization or iteration. Its single-sentence detection accuracy is approximately 85% on the test set. Please read through this article before use to understand potential limitations. The core code (drafts) and trained model files are available on GitHub: lyc8503/AITextDetector Background (aka Useless Rambling) Back when I was still writing my thesis at school half a year ago, rumors were already spreading about checking papers for AIGC (AI-generated content). I tested several platforms—CNKI, Wanfang, and some third-party AIGC detection services—and found they could indeed distinguish between my hand-written text and LLM-generated text with decent accuracy. That sparked my curiosity about how AIGC detection actually works (and how to bypass it) . But I was juggling too many things at the time—obsessed with radio , Minecraft, Touhou—and after a few failed attempts, I shelved the idea. Eventually, I faked my way through the thesis, and life moved on. But recently, while browsing Lofter, I stumbled upon entire tags flooded with low-quality, wildly out-of-character AI-generated fanfics. How can I tell they’re AI at a glance? Well, some folks (or gals) don’t even bother cleaning up Markdown formatting or AI-generated section headers before posting—and then they slap half the article behind a paywall 😓 Most AI-generated texts, however, are harder to spot—they’re buried among diverse writing styles, varied prompts, and not immediately obvious. By the time you realize something feels off, it’s too late. Some texts are borderline impossible to prove as AI, leaving me paranoid. After swallowing a few too many AI-generated turds, I’d finally had enough. Lofter browsing stops here—time to open VS Code! Yes, that’s how I ended up reviving my weekend project idea: building an AI-generated text detector… Research Attempt – No Luck The internet is now almost entirely polluted with ads when searching for AIGC detection. Every result is just another essay-AI-rewriting service. Back then, I dug through the noise and found something called text perplexity . The idea is simple: use an existing LLM to estimate the probability of each word appearing in a given sentence. If nearly every word ranks high in the LLM’s predictions (Top-N), the sentence is likely AI-generated. Conversely, if many words are unexpected, it’s more likely human-written. Sounds promising, right? I spent some time trying this method, but results were disappointing—plenty of false positives and false negatives, and no reasonable threshold could be set. Plus, there are practical issues: high inference cost, poor cross-model generalization, difficulty deploying large models locally, and closed-weight models being hard to integrate. Overall, this approach isn’t elegant or reliable. Failed attempt—got tricked by a bunch of soft-ad "tutorials" A (Somewhat) Successful Attempt – scikit-learn SVM Since online resources were useless, back to old-school alchemy. Scikit-learn, activate! Following its Roadmap , we can directly pick Linear SVC and Naive Bayes as good starting points for our classification task. (Whisper: this also matched my gut feeling—LLMs have detectable word-choice patterns; even a Naive Bayes classifier should pick them up. I just didn’t expect the signal to be this strong.) Data Generation Old-school alchemy traditional classifiers need labeled data—so we need human-written texts and confirmed LLM-generated texts for training. My approach: I pulled data I’d scraped in 2023 from a certain Ford-like and River-like platform, filtering for articles published between 2010–2022 (pre-ChatGPT). I only filtered out extremely low-engagement or very short pieces, then randomly sampled nearly 10,000 multi-thousand-character texts as human-written samples. Then, I used an LLM to generate chapter summaries of these texts, fed the summaries back into the LLM, and had it regenerate full articles. This gave me a roughly equal number of LLM-generated samples, diverse in genre and closely matching the original human content. In theory, at least. But LLM APIs are expensive, and I wasn’t about to spend thousands on a weekend project. So I got creative—and skirted the rules leveraged multiple low-cost or free API channels: Gemini : Used CLIProxyAPI to convert Antigravity/Gemini CLI quota into API access—just pay ~$20 for an AI Pro account Qwen : qwen-code lets you reverse-engineer the Qwen Plus API—free GLM-5 : Lucky timing—OpenRouter was offering free GLM-5 public beta (Pony Alpha) Kimi, Deepseek, Doubao, GLM-4.7 : Signed up during a promotional coding plan—$8.9 first month, API access unlocked Disclaimer: This is not a recommendation. These actions violate platform ToS and may get you banned. But the platforms are too busy with marketing hype to care, and I wasn’t about to pay full price. Many programming-focused LLM APIs strangely charge per call, but we can abuse optimize this by batching tasks into massive inputs, forcing the LLM to generate more content per call. And so… What do you mean I used over 300M Gemini tokens worth $2000 at full price?! Ultimately, I used gemini-3-flash to generate summaries, and seven different models ( gemini-3-pro , qwen-coder-plus , glm-5 , glm-4.7 , kimi-k2.5 , doubao-seed-code , deepseek-v3.2 ) to generate seven sets of LLM-generated samples. The generated files Training While I was halfway through data generation, I couldn’t wait and started training. I asked Claude to write the classifier code, and it naively dumped the entire raw text into the model—achieving a suspicious 99.45% accuracy… Wait, really? Claude’s useless. I’ll do it myself. For training, I split all texts into sentences using Chinese punctuation, cleaned non-Chinese/English characters, then applied scikit-learn’s TF-IDF → LinearSVC . After cleaning up some noise, sentence-level classification still hit ~85% accuracy! Even this buggy first version hit 88% accuracy (later optimized to 85%) Individual sentences carry limited info, but 85% accuracy per sentence means that for a longer article, we can be highly confident in judging whether it’s AI-generated. This performance far exceeded my expectations. Old-school ML still slaps—way better than those dumb online tools that just ask an LLM, “Hey, is this text AI-generated?” After finishing all data, I tried training an 8-class model (human + 7 AIs), but the LLMs seem too similar—probably distilled from each other—so classification was messy, with only ~50% accuracy. Multi-class results—apparently not separable. Maybe my model sucks, but whatever, not important Eventually, I trained seven separate binary classifiers and used majority voting: a sentence is flagged as AI if ≥2 models detect it. All models achieved over 85% accuracy and over 80% F1—pretty solid! I also noticed that AI-generated texts were often flagged by multiple models, so voting made perfect sense. I tried MultinomialNB and SGDClassifier , but accuracy dropped slightly. BERT gave a minor boost but required too much GPU time—discarded. Even tested AutoGluon , which somehow managed only 53% binary accuracy. Won’t dive into those. JS Implementation for Web Demo At this point, I could’ve just published the repo and called it a day. But launching Python every time is way too inconvenient. I could’ve hosted a Python API, but that means