Skip to content

Instantly share code, notes, and snippets.

@alx
Last active April 10, 2023 19:06
Show Gist options
  • Save alx/d1efbedc930a618a73a27a3df0a1e4b6 to your computer and use it in GitHub Desktop.
Save alx/d1efbedc930a618a73a27a3df0a1e4b6 to your computer and use it in GitHub Desktop.
Paragraph of text reports the GPT-2 log prob of that text
// ==UserScript==
// @name OpenAI GPT-2 Detector
// @namespace https://www.jolibrain.com/demo/openai-gpt2-detector-userscript
// @description Paragraph of text reports the GPT-2 log prob of that text
// @author Alexandre Girard <alex.girard@jolibrain.com>
// @version 1.2
// @grant none
// @include https://en.wikipedia.org/wiki/*
// ==/UserScript==
//
// Requirements:
// - Detector server must run on http://localhost:8080 - https://github.com/openai/gpt-2-output-dataset/tree/master/detector
//
// Version History:
//
// 1.2 (2019-11-21): Use granularity feature from feat-detector-granularity branch:
// https://github.com/alx/gpt-2-output-dataset/tree/feat-detector-granilarity
// Add status badges on top of the page
// 1.1 (2019-11-12): Fix userscript @grand and @include headers
// Commented option to only show fakish-detected paragraphs
// 1.0 (2019-11-12): Working demo on https://en.wikipedia.org/*
// Inspired by @karpathy: https://twitter.com/karpathy/status/1192169928079503360
const parsePage = function(htmlElements) {
document.getElementById('botIndex').innerText = 0;
document.getElementById('botCounter').innerText = 0;
const colors = ['#fff5f0','#fee0d2','#fcbba1','#fc9272','#fb6a4a','#ef3b2c','#cb181d','#a50f15','#67000d'];
for(let elementIndex = 0; elementIndex < htmlElements.length; elementIndex++) {
let element = htmlElements[elementIndex];
let text = element.innerText.replace(/[\r\n]+/g, '')
let req = new XMLHttpRequest();
req.open('GET', 'http://localhost:8080/' + elementIndex + '?' + text, true);
req.onreadystatechange = () => {
if (req.readyState !== 4) return;
if (req.status !== 200) throw new Error("HTTP status: " + req.status);
const result = JSON.parse(req.responseText);
const requestIndex = req.responseURL.replace("http://localhost:8080/", "").split("?").shift();
document.getElementById('elementIndex').innerText = requestIndex;
let requestElement = htmlElements[requestIndex]
let mainDivStyle = ""
let predictDivStyle = "font-size: 16px;"
let allTokenStyle = ""
let realWeightStyle = ""
let fakeWeightStyle = ""
let fakeGranulatiry = ""
let botCounter = document.getElementById('botCounter')
let botIndex = "-1"
if(result.all_tokens > 50) {
allTokenStyle = "font-weight: 700;";
}
if(result.real_probability > 0.9) {
realWeightStyle = "color:green; font-weight: 700;"
mainDivStyle = "border-left: 2px solid green;padding-left: 3px;";
}
if(result.fake_probability > 0.9) {
document.getElementById('botCounterDisplay').style.display = 'block';
document.getElementById('botCounterDisplay').style.backgroundColor = '#dc3545';
fakeWeightStyle = "color:red; font-weight: 700;"
mainDivStyle = "border-left: 2px solid red;padding-left: 3px;";
if(result.windows && result.windows.length > 0) {
fakeGranulatiry = "<div style='margin:10px;display:inline-table;'>";
var words = requestElement.innerText.replace(/[\r\n]+/g, '').split(' ');
for(let i = 0; i < words.length; i++) {
var word = words[i];
const vals = result.windows.slice(Math.max(i - 10, 0), i + 1);
const sum = vals
.map(function(a) { return a.fake_probability; })
.reduce(function(a, b) { return a + b; });
const avg = sum / vals.length;
fakeGranulatiry += "<span style='float:left;" +
"background-color: " + colors[parseInt(avg * 10)] + ";" +
"color: " + (avg > 0.5 ? "#fff" : "#000") + ";" +
"padding:2px;'>" + word + "</span>";
}
fakeGranulatiry += "</div>";
}
if(botCounter) {
botIndex = botCounter.innerText
botCounter.innerText = parseInt(botCounter.innerText) + 1
}
}
requestElement = htmlElements[requestIndex]
requestElement.innerHTML = "<div style='" + mainDivStyle + "' id='bot-" + botIndex + "'>" + requestElement.innerHTML + "<div style='" + predictDivStyle + "'> " +
"<span>Tokens: " + result.used_tokens + "/<span style='" + allTokenStyle + "'>" + result.all_tokens + "</span></span> - " +
"<span>By Human | <span style='" + realWeightStyle + "'>"+ result.real_probability.toFixed(2) +
"</span></span> " +
"<progress value=" + result.fake_probability.toFixed(2) + "></progress> " +
"<span style='" + fakeWeightStyle + "'>" + result.fake_probability.toFixed(2) + "</span> | By Robot</span></div>" + fakeGranulatiry + "</div>"
};
req.send();
}
}
const parseableElements = document.getElementsByTagName("p");
const elementCounter = document.createElement("div")
elementCounter.id = 'elementCounterDisplay'
elementCounter.style='height:20px;color: white;background-color: #007bff;padding:3px;'
elementCounter.innerHTML = "<span id='elementIndex'>0</span>/<span id='elementCounter'>" + parseableElements.length + "</span> Elements";
const botCounter = document.createElement("div")
botCounter.id = 'botCounterDisplay'
botCounter.style='display:none;height:20px;color: white;z-index:10;pointer: cursor;padding:3px;'
botCounter.addEventListener("click",function() {
const botIndex = document.getElementById("botIndex");
const nextElement = document.getElementById("bot-" + botIndex.innerText)
if(nextElement) {
nextElement.scrollIntoView();
}
botIndex.innerText = parseInt(botIndex.innerText) >= parseInt(document.getElementById("botCounter").innerText) ? 1 : parseInt(botIndex.innerText) + 1;
return false;
});
botCounter.innerHTML = "<span id='botIndex'>0</span>/<span id='botCounter'>0</span> Robots";
const badgeElements = document.createElement("div")
badgeElements.style='position: fixed; top:0;z-index:10;'
badgeElements.appendChild(elementCounter)
badgeElements.appendChild(botCounter)
document.getElementById("content").appendChild(badgeElements)
parsePage(parseableElements)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment