CoolFace
Apppublic

imseldrith/ChatGPT-Detection

sourceHugging Facegplupdated 3y agoView on Hugging Face
2likes
main.py155 linesDownload Raw Back to root
1import gradio as gr2import spacy3import re4import numpy as np5import torch6from transformers import AutoTokenizer, AutoModelForCausalLM7 8# Define some constants for error messages9MAX_TEXT_LENGTH = 204810MIN_GEN_LENGTH = 111MAX_GEN_LENGTH = 204812MIN_AI_PERCENTAGE = 5013 14# Download the Spacy model for English15spacy.cli.download("en_core_web_sm")16nlp = spacy.load("en_core_web_sm")17 18# Define a function to detect AI-generated content and calculate the perplexity score,19# burstiness score, and average perplexity score for a given text input20def detect_ai_content(text, max_gen_length, temperature, model_name, model_size, num_return_sequences, min_ai_percentage):21    # Clean the text by removing extra spaces, line breaks, and special characters22    cleaned_text = re.sub(r'\s+', ' ', text).strip()23    cleaned_text = re.sub(r'[^\w\s]', '', cleaned_text)24 25    # If the cleaned text is empty or contains only one sentence, return an error message26    doc = nlp(cleaned_text)27    if not re.search('\S', cleaned_text) or len(list(doc.sents)) < 2:28        return {"error": "Input text must contain at least two sentences."}29 30    # Check if the cleaned text is longer than the maximum allowed by the GPT model31    if len(cleaned_text) > MAX_TEXT_LENGTH:32        return {"error": f"Input text must be no longer than {MAX_TEXT_LENGTH} characters."}33 34    # Check if the minimum threshold for the percentage of AI-generated content is within the allowed range35    if not (0 <= min_ai_percentage <= 100):36        return {"error": "Minimum threshold for AI percentage must be between 0 and 100."}37 38    # Load the specified GPT model and tokenizer39    model_name = f"{model_name}-{model_size}"40    tokenizer = AutoTokenizer.from_pretrained(model_name)41    model = AutoModelForCausalLM.from_pretrained(model_name)42 43    # Set the device to run the model on (either "cuda" or "cpu")44    device = "cuda" if torch.cuda.is_available() else "cpu"45    model.to(device)46 47    # Set the end of sequence token ID for text generation48    eos_token_id = tokenizer.eos_token_id49 50    # Generate multiple sequences using the pre-trained GPT model51    input_ids = tokenizer.encode(cleaned_text, add_special_tokens=True, return_tensors='pt').to(device)52 53    output_sequences = []54    for i in range(num_return_sequences):55        output_sequence = model.generate(56            input_ids=input_ids,57            max_length=max_gen_length + len(input_ids[0]),58            temperature=temperature,59            top_k=50,60            top_p=0.95,61            repetition_penalty=1.5,62            do_sample=True,63            num_return_sequences=164        )[0]65        output_sequences.append(output_sequence)66    67    # Decode the generated sequences using the GPT tokenizer68    generated_texts = []69    perplexities = []70    ai_percentages = []71 72    for i, output_sequence in enumerate(output_sequences):73        generated_text = tokenizer.decode(output_sequence.tolist()[len(input_ids[0]):], skip_special_tokens=True)74 75        # Calculate the percentage of AI-generated content in the generated text76        ai_percentage = round(len(generated_text) / len(cleaned_text) * 100, 2)77        ai_percentages.append(ai_percentage)78 79        # Check if the AI percentage and perplexity score are above their respective thresholds80        generated_input_ids = tokenizer.encode(generated_text, add_special_tokens=False, return_tensors='pt').to(device)81        with torch.no_grad():82            loss = model(generated_input_ids, labels=generated_input_ids).loss.item()83        perplexity = np.exp(loss)84        perplexities.append(perplexity)85        generated_texts.append(generated_text)86 87    # Remove the generated sequences that are identical or highly similar to the cleaned text88    clean_doc = nlp(cleaned_text)89    unique_generated_texts = []90 91    for generated_text in generated_texts:92        gen_doc = nlp(generated_text)93        similarity = clean_doc.similarity(gen_doc)94 95        if similarity < 0.8:96            is_unique = True97 98            for unique_text in unique_generated_texts:99                unique_doc = nlp(unique_text)100                unique_similarity = unique_doc.similarity(gen_doc)101 102                if unique_similarity >= 0.8:103                    is_unique = False104                    break105 106            if is_unique:107                unique_generated_texts.append(generated_text)108 109    # Calculate the burstiness score for the input text, which measures the diversity of vocabulary in the input text110    doc = nlp(cleaned_text)111    # Extract the tokens from the input text's sentences112    all_tokens = []113    for sent in doc.sents:114        tokens = [token.text.lower() for token in sent if not token.is_punct and not token.is_stop]115        all_tokens += tokens116 117    # Calculate the burstiness score for the input text118    unique_tokens = set(all_tokens)119    num_unique_tokens = len(unique_tokens)120    total_tokens = len(all_tokens)121    burstiness_score = (num_unique_tokens * num_unique_tokens) / (total_tokens * total_tokens)122 123    # Calculate the average perplexity score and AI percentage for the generated texts124    avg_perplexity = np.mean(perplexities)125    avg_ai_percentage = round(np.mean(ai_percentages), 2)126 127    # Check if the AI percentage and perplexity score are above their respective thresholds128    if avg_ai_percentage < min_ai_percentage:129        return {"error": f"The generated text has an AI percentage of {avg_ai_percentage}%, which is below the minimum threshold of {min_ai_percentage}%."}130    if avg_perplexity < MIN_GEN_LENGTH:131        return {"error": f"The generated text has a perplexity score of {avg_perplexity}, which is below the minimum threshold of {MIN_GEN_LENGTH}."}132    if avg_perplexity > MAX_GEN_LENGTH:133        return {"error": f"The generated text has a perplexity score of {avg_perplexity}, which is above the maximum threshold of {MAX_GEN_LENGTH}."}134 135    # Return the unique generated texts, burstiness score, and average AI percentage and perplexity score136    return {137        "generated_texts": unique_generated_texts,138        "burstiness_score": round(burstiness_score, 2),139        "avg_ai_percentage": avg_ai_percentage,140        "avg_perplexity": round(avg_perplexity, 2)141    }142 143# Define the Gradio interface for the BAI Chat function144def bai_chat(text, max_gen_length=256, temperature=0.7, model_name="gpt2", model_size="medium", num_return_sequences=5, min_ai_percentage=50):145    result = detect_ai_content(text, max_gen_length, temperature, model_name, model_size, num_return_sequences, min_ai_percentage)146 147    if "error" in result:148        return result["error"]149    else:150        generated_texts = "\n\n".join(result["generated_texts"])151        return f"Burstiness Score: {result['burstiness_score']}\nAverage AI Percentage: {result['avg_ai_percentage']}%\nAverage Perplexity Score: {result['avg_perplexity']}\n\n{generated_texts}"152 153gr.Interface(fn=bai_chat, 154            inputs=[gr.inputs.Textbox("Enter your text here...")], 155            outputs=[gr.outputs.Textbox(label="Generated Texts")]).launch()