humanizer / app.py
mutij8's picture
Update app.py
dea3c78 verified
Raw History Blame Contribute Delete
3.15 kB
import spaces
import gradio as gr
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
from peft import PeftModel
base_model_id = "unsloth/llama-3-8b-Instruct-bnb-4bit"
adapter_model_id = "mutij8/academic-humanizer-llama3"
# Global variables (loaded lazily on first request)
tokenizer = None
model = None
def load_model_once():
global tokenizer, model
if model is not None:
return tokenizer, model
print("⏳ ZeroGPU allocated! Loading model into VRAM...")
tokenizer = AutoTokenizer.from_pretrained(adapter_model_id)
base_model = AutoModelForCausalLM.from_pretrained(
base_model_id,
torch_dtype=torch.float16,
device_map="cuda"
)
model = PeftModel.from_pretrained(base_model, adapter_model_id)
print("✅ Model loaded successfully on GPU!")
return tokenizer, model
@spaces.GPU
def humanize_paragraph(paragraph):
paragraph = paragraph.strip()
if not paragraph:
return "Please enter a valid academic paragraph."
tok, mod = load_model_once()
word_count = len(paragraph.split())
sft_instruction = f'''You are a human researcher hastily writing a draft for an Essay.
- Tone: Write with natural human imperfection, varied sentence lengths (mixing very short and long sentences), and stylistic asymmetry.
- Rule 1: Output MUST be between {int(word_count*0.85)} and {int(word_count*1.15)} words.
- Rule 2: Force clause inversion. Actively rewrite the paragraph structures by shifting the order of clauses (e.g., start with the consequence, context, or ending arguments rather than the original opening clauses).
- Rule 3: Use highly varied sentence structures and alternative vocabulary choices to avoid contiguous 3-to-5 word matches with the source, preventing plagiarism detection.
- Rule 4: Keep all inline citations (e.g. [1] or (Smith, 2023)) 100% intact.
- Rule 5: Maintain the precise narrative tense of the original text (do not change past tense to present or present tense to past).
- Rule 6: Output ONLY the rewritten text.'''
messages = [
{"role": "system", "content": sft_instruction},
{"role": "user", "content": paragraph}
]
prompt = tok.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
inputs = tok([prompt], return_tensors="pt").to("cuda")
outputs = mod.generate(
**inputs,
max_new_tokens=int(word_count * 1.5) + 30,
do_sample=True,
temperature=0.85,
top_p=0.95,
top_k=50
)
input_len = inputs["input_ids"].shape[1]
generated_text = tok.decode(outputs[0][input_len:], skip_special_tokens=True).strip()
return generated_text
interface = gr.Interface(
fn=humanize_paragraph,
inputs=gr.Textbox(lines=10, placeholder="Enter AI-style academic paragraph here..."),
outputs=gr.Textbox(lines=10, label="Humanized Paragraph (Low Plagiarism & Low AI Score)"),
title="Turnitin-Calibrated Essay Humanizer",
description="Input a paragraph to rewrite it using humanized structures, clause inversion, and exact tense retention."
)
if __name__ == "__main__":
interface.launch()