Spaces:
Running
on
Zero
Running
on
Zero
Added detection mode
Browse files- binoculars/detector.py +24 -2
- demo/demo.py +32 -11
binoculars/detector.py
CHANGED
@@ -11,7 +11,10 @@ from .metrics import perplexity, entropy
|
|
11 |
|
12 |
torch.set_grad_enabled(False)
|
13 |
|
14 |
-
|
|
|
|
|
|
|
15 |
DEVICE_1 = "cuda:0" if torch.cuda.is_available() else "cpu"
|
16 |
DEVICE_2 = "cuda:1" if torch.cuda.device_count() > 1 else DEVICE_1
|
17 |
|
@@ -22,9 +25,17 @@ class Binoculars(object):
|
|
22 |
performer_name_or_path: str = "tiiuae/falcon-7b-instruct",
|
23 |
use_bfloat16: bool = True,
|
24 |
max_token_observed: int = 512,
|
|
|
25 |
) -> None:
|
26 |
assert_tokenizer_consistency(observer_name_or_path, performer_name_or_path)
|
27 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
self.observer_model = AutoModelForCausalLM.from_pretrained(observer_name_or_path,
|
29 |
device_map={"": DEVICE_1},
|
30 |
trust_remote_code=True,
|
@@ -49,6 +60,14 @@ class Binoculars(object):
|
|
49 |
|
50 |
self.max_token_observed = max_token_observed
|
51 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
def _tokenize(self, batch: list[str]) -> transformers.BatchEncoding:
|
53 |
batch_size = len(batch)
|
54 |
encodings = self.tokenizer(
|
@@ -81,5 +100,8 @@ class Binoculars(object):
|
|
81 |
|
82 |
def predict(self, input_text: Union[list[str], str]) -> Union[list[str], str]:
|
83 |
binoculars_scores = np.array(self.compute_score(input_text))
|
84 |
-
pred = np.where(binoculars_scores <
|
|
|
|
|
|
|
85 |
return pred
|
|
|
11 |
|
12 |
torch.set_grad_enabled(False)
|
13 |
|
14 |
+
# selected using Falcon-7B and Falcon-7B-Instruct at bfloat16
|
15 |
+
BINOCULARS_ACCURACY_THRESHOLD = 0.9015310749276843 # optimized for f1-score
|
16 |
+
BINOCULARS_FPR_THRESHOLD = 0.8536432310785527 # optimized for low-fpr
|
17 |
+
|
18 |
DEVICE_1 = "cuda:0" if torch.cuda.is_available() else "cpu"
|
19 |
DEVICE_2 = "cuda:1" if torch.cuda.device_count() > 1 else DEVICE_1
|
20 |
|
|
|
25 |
performer_name_or_path: str = "tiiuae/falcon-7b-instruct",
|
26 |
use_bfloat16: bool = True,
|
27 |
max_token_observed: int = 512,
|
28 |
+
mode: str = "low-fpr",
|
29 |
) -> None:
|
30 |
assert_tokenizer_consistency(observer_name_or_path, performer_name_or_path)
|
31 |
|
32 |
+
if mode == "low-fpr":
|
33 |
+
self.threshold = BINOCULARS_FPR_THRESHOLD
|
34 |
+
elif mode == "accuracy":
|
35 |
+
self.threshold = BINOCULARS_ACCURACY_THRESHOLD
|
36 |
+
else:
|
37 |
+
raise ValueError(f"Invalid mode: {mode}")
|
38 |
+
|
39 |
self.observer_model = AutoModelForCausalLM.from_pretrained(observer_name_or_path,
|
40 |
device_map={"": DEVICE_1},
|
41 |
trust_remote_code=True,
|
|
|
60 |
|
61 |
self.max_token_observed = max_token_observed
|
62 |
|
63 |
+
def change_mode(self, mode: str) -> None:
|
64 |
+
if mode == "low-fpr":
|
65 |
+
self.threshold = BINOCULARS_FPR_THRESHOLD
|
66 |
+
elif mode == "accuracy":
|
67 |
+
self.threshold = BINOCULARS_ACCURACY_THRESHOLD
|
68 |
+
else:
|
69 |
+
raise ValueError(f"Invalid mode: {mode}")
|
70 |
+
|
71 |
def _tokenize(self, batch: list[str]) -> transformers.BatchEncoding:
|
72 |
batch_size = len(batch)
|
73 |
encodings = self.tokenizer(
|
|
|
100 |
|
101 |
def predict(self, input_text: Union[list[str], str]) -> Union[list[str], str]:
|
102 |
binoculars_scores = np.array(self.compute_score(input_text))
|
103 |
+
pred = np.where(binoculars_scores < self.threshold,
|
104 |
+
"Most likely AI-generated",
|
105 |
+
"Most likely human-generated"
|
106 |
+
).tolist()
|
107 |
return pred
|
demo/demo.py
CHANGED
@@ -19,6 +19,16 @@ def run_detector(input_str):
|
|
19 |
return f"{BINO.predict(input_str)}"
|
20 |
|
21 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
# def load_set(progress=gr.Progress()):
|
23 |
# tokens = [None] * 24
|
24 |
# for count in progress.tqdm(tokens, desc="Counting Tokens..."):
|
@@ -41,6 +51,8 @@ css = """
|
|
41 |
}
|
42 |
"""
|
43 |
|
|
|
|
|
44 |
capybara_problem = '''Dr. Capy Cosmos, a capybara unlike any other, astounded the scientific community with his groundbreaking research in astrophysics. With his keen sense of observation and unparalleled ability to interpret cosmic data, he uncovered new insights into the mysteries of black holes and the origins of the universe. As he peered through telescopes with his large, round eyes, fellow researchers often remarked that it seemed as if the stars themselves whispered their secrets directly to him. Dr. Cosmos not only became a beacon of inspiration to aspiring scientists but also proved that intellect and innovation can be found in the most unexpected of creatures.'''
|
45 |
|
46 |
with gr.Blocks(css=css,
|
@@ -60,10 +72,16 @@ with gr.Blocks(css=css,
|
|
60 |
with gr.Row():
|
61 |
input_box = gr.Textbox(value=capybara_problem, placeholder="Enter text here", lines=8, label="Input Text", )
|
62 |
with gr.Row():
|
63 |
-
|
|
|
|
|
|
|
|
|
|
|
64 |
submit_button = gr.Button("Run Binoculars", variant="primary")
|
|
|
65 |
with gr.Row():
|
66 |
-
output_text = gr.Textbox(label="Prediction", value="AI-Generated")
|
67 |
|
68 |
with gr.Row():
|
69 |
gr.HTML("<p><p><p>")
|
@@ -76,16 +94,18 @@ with gr.Blocks(css=css,
|
|
76 |
gr.Markdown(
|
77 |
"""
|
78 |
- `Accuracy` :
|
79 |
-
- AI-generated text detectors aim for accuracy, but
|
80 |
-
-
|
|
|
|
|
81 |
- Users are advised to exercise discretion, and we assume no liability for any use.
|
82 |
-
- `
|
83 |
-
- In this work, our focus is
|
84 |
-
-
|
85 |
-
- `
|
86 |
-
-
|
87 |
-
|
88 |
-
-
|
89 |
"""
|
90 |
)
|
91 |
|
@@ -109,3 +129,4 @@ with gr.Blocks(css=css,
|
|
109 |
# clear_button.click(lambda x: input_box., )
|
110 |
submit_button.click(run_detector, inputs=input_box, outputs=output_text)
|
111 |
clear_button.click(lambda: ("", ""), outputs=[input_box, output_text])
|
|
|
|
19 |
return f"{BINO.predict(input_str)}"
|
20 |
|
21 |
|
22 |
+
def change_mode(mode):
|
23 |
+
if mode == "Low False Positive Rate":
|
24 |
+
BINO.change_mode("low-fpr")
|
25 |
+
elif mode == "High Accuracy":
|
26 |
+
BINO.change_mode("accuracy")
|
27 |
+
else:
|
28 |
+
gr.Error(f"Invalid mode selected.")
|
29 |
+
return mode
|
30 |
+
|
31 |
+
|
32 |
# def load_set(progress=gr.Progress()):
|
33 |
# tokens = [None] * 24
|
34 |
# for count in progress.tqdm(tokens, desc="Counting Tokens..."):
|
|
|
51 |
}
|
52 |
"""
|
53 |
|
54 |
+
# Most likely human generated, #most likely AI written
|
55 |
+
|
56 |
capybara_problem = '''Dr. Capy Cosmos, a capybara unlike any other, astounded the scientific community with his groundbreaking research in astrophysics. With his keen sense of observation and unparalleled ability to interpret cosmic data, he uncovered new insights into the mysteries of black holes and the origins of the universe. As he peered through telescopes with his large, round eyes, fellow researchers often remarked that it seemed as if the stars themselves whispered their secrets directly to him. Dr. Cosmos not only became a beacon of inspiration to aspiring scientists but also proved that intellect and innovation can be found in the most unexpected of creatures.'''
|
57 |
|
58 |
with gr.Blocks(css=css,
|
|
|
72 |
with gr.Row():
|
73 |
input_box = gr.Textbox(value=capybara_problem, placeholder="Enter text here", lines=8, label="Input Text", )
|
74 |
with gr.Row():
|
75 |
+
# dropdown option for mode
|
76 |
+
dropdown_mode = gr.Dropdown(["Low False Positive Rate", "High Accuracy"],
|
77 |
+
label="Mode",
|
78 |
+
show_label=True,
|
79 |
+
value="Low False Positive Rate"
|
80 |
+
)
|
81 |
submit_button = gr.Button("Run Binoculars", variant="primary")
|
82 |
+
clear_button = gr.ClearButton()
|
83 |
with gr.Row():
|
84 |
+
output_text = gr.Textbox(label="Prediction", value="Most likely AI-Generated")
|
85 |
|
86 |
with gr.Row():
|
87 |
gr.HTML("<p><p><p>")
|
|
|
94 |
gr.Markdown(
|
95 |
"""
|
96 |
- `Accuracy` :
|
97 |
+
- AI-generated text detectors aim for accuracy, but no detector is perfect.
|
98 |
+
- If you choose "high accuracy" mode, then the threshold between human and machine is chosen to maximize the F1 score on our validation dataset.
|
99 |
+
- If you choose the "low false-positive rate" mode, the threshold for declaring something to be AI generated will be set so that the false positive (human text wrongly flagged as AI) rate is below 0.01% on our validation set.
|
100 |
+
- The provided prediction is for demonstration purposes only. This is not offered as a consumer product.
|
101 |
- Users are advised to exercise discretion, and we assume no liability for any use.
|
102 |
+
- `Recommended detection Use Cases` :
|
103 |
+
- In this work, our focus is on achieving a low false positive rate, crucial for sensitive downstream use cases where false accusations are highly undesireable.
|
104 |
+
- The main focus of our research is on content moderation, e.g., detecting AI-generated reviews on Amazon/Yelp, detecting AI generated social media posts and news, etc. We feel this application space is most compelling, as LLM detection tools are best used by professionals in conjunction with a broader set of moderation tools and policies.
|
105 |
+
- `Known weaknesses` :
|
106 |
+
- As noted in our paper, Binoculars exhibits superior detection performance in the English language compared to other languages. Non-English text makes it more likely that results will default to "human written."
|
107 |
+
- Binoculars considers verbatim memorized texts to be "AI generated." For example, most language models have memorized and can recite the US constitution. For this reason, text from the constitution, or other highly memorized sources, may be classified as AI written.
|
108 |
+
- We recommend using 200-300 words of text at a time. Fewer words make detection difficult, as can using more than 1000 words. Binoculars will be more likely to default to the "human written" category if too few tokens are provided.
|
109 |
"""
|
110 |
)
|
111 |
|
|
|
129 |
# clear_button.click(lambda x: input_box., )
|
130 |
submit_button.click(run_detector, inputs=input_box, outputs=output_text)
|
131 |
clear_button.click(lambda: ("", ""), outputs=[input_box, output_text])
|
132 |
+
dropdown_mode.change(change_mode, inputs=[dropdown_mode], outputs=[dropdown_mode])
|