ahans30 commited on
Commit
1008577
1 Parent(s): 45f9856

Added detection mode

Browse files
Files changed (2) hide show
  1. binoculars/detector.py +24 -2
  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
- GLOBAL_BINOCULARS_THRESHOLD = 0.9015310749276843 # selected using Falcon-7B and Falcon-7B-Instruct at bfloat16
 
 
 
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 < GLOBAL_BINOCULARS_THRESHOLD, "AI-Generated", "Human-Generated").tolist()
 
 
 
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
- clear_button = gr.ClearButton()
 
 
 
 
 
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 achieving 100% is challenging.
80
- - The provided prediction is for demo purposes only and should not be considered a consumer product.
 
 
81
  - Users are advised to exercise discretion, and we assume no liability for any use.
82
- - `Detection Use Cases` :
83
- - In this work, our focus is to achieve an ultra-low false positive rate, crucial for sensitive downstream use case (e.g., avoiding false accusations in academic honesty cases).
84
- - We find optimal application in content moderation, for example in detecting AI-generated reviews on platforms like Amazon, Google, Yelp, etc. This represents one of the most compelling and noteworthy use cases for Binoculars.
85
- - `Human Supervision Advisory` :
86
- - Strongly caution against using Binoculars (or any detector) without human supervision.
87
- - `Performance by Language` :
88
- - As noted in our paper, Binoculars exhibit superior detection performance in the English language compared to other languages.
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])