|
import gradio as gr |
|
from huggingface_hub import InferenceClient |
|
from transformers import SynthIDTextWatermarkingConfig |
|
|
|
class SynthIDApp: |
|
def __init__(self): |
|
self.client = None |
|
self.watermarking_config = None |
|
self.WATERMARK_KEYS = [654, 400, 836, 123, 340, 443, 597, 160, 57, 789] |
|
|
|
def login(self, hf_token): |
|
"""Initialize the inference client with authentication.""" |
|
try: |
|
|
|
self.client = InferenceClient( |
|
model="google/gemma-2b", |
|
token=hf_token |
|
) |
|
|
|
|
|
_ = self.client.text_generation("Test", max_new_tokens=1) |
|
return "Inference client initialized successfully!" |
|
except Exception as e: |
|
self.client = None |
|
return f"Error initializing client: {str(e)}" |
|
|
|
def update_watermark_config(self, ngram_len): |
|
"""Update the watermarking configuration with new ngram_len.""" |
|
try: |
|
self.watermarking_config = SynthIDTextWatermarkingConfig( |
|
keys=self.WATERMARK_KEYS, |
|
ngram_len=ngram_len |
|
) |
|
return f"Watermark config updated: ngram_len = {ngram_len}" |
|
except Exception as e: |
|
return f"Error updating config: {str(e)}" |
|
|
|
def apply_watermark(self, text, ngram_len): |
|
"""Apply SynthID watermark to input text using the inference endpoint.""" |
|
if not self.client: |
|
return text, "Error: Client not initialized. Please login first." |
|
|
|
try: |
|
|
|
self.update_watermark_config(ngram_len) |
|
|
|
|
|
watermark_dict = { |
|
"keys": self.watermarking_config.keys, |
|
"ngram_len": self.watermarking_config.ngram_len |
|
} |
|
|
|
|
|
response = self.client.text_generation( |
|
text, |
|
max_new_tokens=100, |
|
do_sample=True, |
|
temperature=0.7, |
|
top_p=0.9, |
|
watermarking_config=watermark_dict, |
|
return_full_text=False |
|
) |
|
|
|
watermarked_text = response |
|
return watermarked_text, f"Watermark applied successfully! (ngram_len: {ngram_len})" |
|
except Exception as e: |
|
return text, f"Error applying watermark: {str(e)}" |
|
|
|
def analyze_text(self, text): |
|
"""Analyze text characteristics.""" |
|
try: |
|
total_words = len(text.split()) |
|
avg_word_length = sum(len(word) for word in text.split()) / total_words if total_words > 0 else 0 |
|
char_count = len(text) |
|
|
|
analysis = f"""Text Analysis: |
|
- Total characters: {char_count} |
|
- Total words: {total_words} |
|
- Average word length: {avg_word_length:.2f} |
|
|
|
Note: This is a basic analysis. The official SynthID detector is not yet available in the public transformers package.""" |
|
|
|
return analysis |
|
except Exception as e: |
|
return f"Error analyzing text: {str(e)}" |
|
|
|
|
|
app_instance = SynthIDApp() |
|
|
|
with gr.Blocks(title="SynthID Text Watermarking Tool") as app: |
|
gr.Markdown("# SynthID Text Watermarking Tool") |
|
gr.Markdown("Using Hugging Face Inference Endpoints for faster processing") |
|
|
|
|
|
with gr.Row(): |
|
hf_token = gr.Textbox( |
|
label="Enter Hugging Face Token", |
|
type="password", |
|
placeholder="hf_..." |
|
) |
|
login_status = gr.Textbox(label="Login Status") |
|
login_btn = gr.Button("Login") |
|
login_btn.click(app_instance.login, inputs=[hf_token], outputs=[login_status]) |
|
|
|
with gr.Tab("Apply Watermark"): |
|
with gr.Row(): |
|
with gr.Column(scale=3): |
|
input_text = gr.Textbox( |
|
label="Input Text", |
|
lines=5, |
|
placeholder="Enter text to watermark..." |
|
) |
|
output_text = gr.Textbox(label="Watermarked Text", lines=5) |
|
with gr.Column(scale=1): |
|
ngram_len = gr.Slider( |
|
label="N-gram Length", |
|
minimum=2, |
|
maximum=5, |
|
step=1, |
|
value=5, |
|
info="Controls watermark detectability (2-5)" |
|
) |
|
status = gr.Textbox(label="Status") |
|
|
|
gr.Markdown(""" |
|
### N-gram Length Parameter: |
|
- Higher values (4-5): More detectable watermark, but more brittle to changes |
|
- Lower values (2-3): More robust to changes, but harder to detect |
|
- Default (5): Maximum detectability""") |
|
|
|
apply_btn = gr.Button("Apply Watermark") |
|
apply_btn.click( |
|
app_instance.apply_watermark, |
|
inputs=[input_text, ngram_len], |
|
outputs=[output_text, status] |
|
) |
|
|
|
with gr.Tab("Analyze Text"): |
|
with gr.Row(): |
|
analyze_input = gr.Textbox( |
|
label="Text to Analyze", |
|
lines=5, |
|
placeholder="Enter text to analyze..." |
|
) |
|
analyze_result = gr.Textbox(label="Analysis Result", lines=5) |
|
analyze_btn = gr.Button("Analyze Text") |
|
analyze_btn.click(app_instance.analyze_text, inputs=[analyze_input], outputs=[analyze_result]) |
|
|
|
gr.Markdown(""" |
|
### Instructions: |
|
1. Enter your Hugging Face token and click Login |
|
2. Once connected, you can use the tabs to apply watermarks or analyze text |
|
3. Adjust the N-gram Length slider to control watermark characteristics |
|
|
|
### Notes: |
|
- This version uses Hugging Face's Inference Endpoints for faster processing |
|
- No model download required - everything runs in the cloud |
|
- The watermark is designed to be imperceptible to humans |
|
- This demo only implements watermark application |
|
- The official detector will be available in future releases |
|
- For production use, use your own secure watermark keys |
|
- Your token is never stored and is only used for API access |
|
""") |
|
|
|
|
|
if __name__ == "__main__": |
|
app.launch() |