catninja123's picture
Upload app.py with huggingface_hub
84eeede verified
Raw
History Blame Contribute Delete
3.79 kB
"""
DIPPER Paraphrase API — HuggingFace Spaces deployment (GPU-enabled).
Uses google/t5-efficient-large-nl32 tokenizer with SamSJackson/paraphrase-dipper-no-ctx model.
"""
import gradio as gr
import torch
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
import time
device = "cuda" if torch.cuda.is_available() else "cpu"
print(f"[DIPPER] Device: {device}")
print("[DIPPER] Loading model...")
t0 = time.time()
# CRITICAL: tokenizer must come from the base model, NOT from SamSJackson repo (which has broken vocab=104)
tokenizer = AutoTokenizer.from_pretrained("google/t5-efficient-large-nl32")
model = AutoModelForSeq2SeqLM.from_pretrained("SamSJackson/paraphrase-dipper-no-ctx")
model = model.to(device)
model.eval()
print(f"[DIPPER] Model loaded in {time.time()-t0:.1f}s on {device}")
print(f"[DIPPER] Tokenizer vocab: {tokenizer.vocab_size}, Model params: {sum(p.numel() for p in model.parameters())/1e6:.1f}M")
# Self-test
test_input = "lexical = 40, order = 40 This is a test sentence about machine learning and artificial intelligence."
test_ids = tokenizer(test_input, return_tensors="pt", max_length=512, truncation=True)
test_ids = {k: v.to(device) for k, v in test_ids.items()}
with torch.no_grad():
test_out = model.generate(**test_ids, max_new_tokens=128, top_p=0.75, do_sample=True)
test_result = tokenizer.decode(test_out[0], skip_special_tokens=True)
print(f"[DIPPER] Self-test result: '{test_result}'")
def paraphrase(text: str, lex: int = 40, order: int = 40) -> str:
"""Paraphrase a single paragraph using DIPPER."""
if not text or not text.strip():
return ""
text = text.strip()
prefix = f"lexical = {lex}, order = {order} "
input_text = prefix + text
inputs = tokenizer(input_text, return_tensors="pt", max_length=1000, truncation=True)
inputs = {k: v.to(device) for k, v in inputs.items()}
t0 = time.time()
with torch.no_grad():
outputs = model.generate(
**inputs,
max_new_tokens=500,
top_p=0.75,
do_sample=True
)
elapsed = time.time() - t0
result = tokenizer.decode(outputs[0], skip_special_tokens=True)
print(f"[DIPPER] {len(text)} -> {len(result)} chars in {elapsed:.1f}s")
return result
def batch_paraphrase(text: str, lex: int = 40, order: int = 40) -> str:
"""Paraphrase multi-paragraph text by processing each paragraph separately."""
if not text or not text.strip():
return ""
paragraphs = [p.strip() for p in text.split('\n\n') if p.strip()]
results = []
for i, para in enumerate(paragraphs):
print(f"[DIPPER] Paragraph {i+1}/{len(paragraphs)}")
result = paraphrase(para, lex=lex, order=order)
results.append(result)
return '\n\n'.join(results)
# Gradio interface
with gr.Blocks(title="DIPPER Paraphrase API") as demo:
gr.Markdown("# DIPPER Paraphrase API\nRewrite text to bypass AI detection. Use the API endpoint for programmatic access.")
gr.Markdown(f"**Device:** {device} | **Tokenizer:** google/t5-efficient-large-nl32 | **Model:** SamSJackson/paraphrase-dipper-no-ctx (972M)")
with gr.Row():
with gr.Column():
input_text = gr.Textbox(label="Input Text", lines=10, placeholder="Paste text here...")
lex_slider = gr.Slider(0, 100, value=40, step=10, label="Lexical Control (40=optimal)")
ord_slider = gr.Slider(0, 100, value=40, step=10, label="Order Control (40=optimal)")
btn = gr.Button("Paraphrase", variant="primary")
with gr.Column():
output_text = gr.Textbox(label="Paraphrased Text", lines=10)
btn.click(fn=batch_paraphrase, inputs=[input_text, lex_slider, ord_slider], outputs=output_text)
demo.launch()