Download app.py from mutij8/humanizer: direct link, hf CLI and curl.
- Browser
- Download file 3.15 kB
-
https://huggingface.co/spaces/mutij8/humanizer/resolve/main/app.py
- Command line
-
hf download hf://spaces/mutij8/humanizer/app.py
-
curl -L -o app.py https://huggingface.co/spaces/mutij8/humanizer/resolve/main/app.py
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 | |
| 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() |