WenqingZhang commited on
Commit
772819f
1 Parent(s): 23e0b1c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +49 -115
app.py CHANGED
@@ -1,8 +1,6 @@
1
  import gradio as gr
2
  from requests import head
3
  from transformer_vectorizer import TransformerVectorizer
4
- from sklearn.feature_extraction.text import TfidfVectorizer
5
- import numpy as np
6
  from concrete.ml.deployment import FHEModelClient
7
  import numpy
8
  import os
@@ -26,18 +24,12 @@ time.sleep(5)
26
  # (encrypted data is too large to display in the browser)
27
  ENCRYPTED_DATA_BROWSER_LIMIT = 500
28
  N_USER_KEY_STORED = 20
29
- model_names=['financial_rating','legal_rating']
30
-
31
-
32
  FHE_MODEL_PATH = "deployment/financial_rating"
33
- FHE_LEGAL_PATH = "deployment/legal_rating"
34
- #FHE_LEGAL_PATH="deployment/legal_rating"
35
 
36
  print("Loading the transformer model...")
37
 
38
  # Initialize the transformer vectorizer
39
  transformer_vectorizer = TransformerVectorizer()
40
- vectorizer = TfidfVectorizer()
41
 
42
  def clean_tmp_directory():
43
  # Allow 20 user keys to be stored.
@@ -57,69 +49,38 @@ def clean_tmp_directory():
57
  for user_id in user_ids:
58
  if file.name.endswith(f"{user_id}.npy"):
59
  file.unlink()
60
- mes=[]
61
 
62
- def keygen(selected_tasks):
 
63
  # Clean tmp directory if needed
64
  clean_tmp_directory()
65
 
66
  print("Initializing FHEModelClient...")
67
 
68
-
69
-
70
- if not selected_tasks:
71
- return "choose a task first" # 修改提示信息为英文
72
  user_id = numpy.random.randint(0, 2**32)
73
- if "legal_rating" in selected_tasks:
74
- model_names.append('legal_rating')
75
- # Let's create a user_id
76
-
77
- fhe_api= FHEModelClient(FHE_LEGAL_PATH, f".fhe_keys/{user_id}")
78
-
79
 
80
- if "financial_rating" in selected_tasks:
81
- model_names.append('financial_rating')
82
 
83
- fhe_api = FHEModelClient(FHE_MODEL_PATH, f".fhe_keys/{user_id}")
84
-
85
- # Let's create a user_id
86
-
87
-
88
- fhe_api.load()
89
-
90
-
91
- # Generate a fresh key
92
  fhe_api.generate_private_and_evaluation_keys(force=True)
93
  evaluation_key = fhe_api.get_serialized_evaluation_keys()
94
-
95
- # Save evaluation_key in a file, since too large to pass through regular Gradio
96
- # buttons, https://github.com/gradio-app/gradio/issues/1877
97
  numpy.save(f"tmp/tmp_evaluation_key_{user_id}.npy", evaluation_key)
98
 
99
  return [list(evaluation_key)[:ENCRYPTED_DATA_BROWSER_LIMIT], user_id]
100
 
101
 
102
-
103
-
104
-
105
  def encode_quantize_encrypt(text, user_id):
106
  if not user_id:
107
  raise gr.Error("You need to generate FHE keys first.")
108
- if "legal_rating" in model_names:
109
- fhe_api = FHEModelClient(FHE_LEGAL_PATH, f".fhe_keys/{user_id}")
110
- encodings =vectorizer.fit_transform([text]).toarray()
111
- if encodings.shape[1] < 1736:
112
- # 在后面填充零
113
- padding = np.zeros((1, 1736 - encodings.shape[1]))
114
- encodings = np.hstack((encodings, padding))
115
- elif encodings.shape[1] > 1736:
116
- # 截取前1736列
117
- encodings = encodings[:, :1736]
118
- else:
119
- fhe_api = FHEModelClient(FHE_MODEL_PATH, f".fhe_keys/{user_id}")
120
- encodings = transformer_vectorizer.transform([text])
121
-
122
  fhe_api.load()
 
123
  quantized_encodings = fhe_api.model.quantize_input(encodings).astype(numpy.uint8)
124
  encrypted_quantized_encoding = fhe_api.quantize_encrypt_serialize(encodings)
125
 
@@ -137,7 +98,6 @@ def encode_quantize_encrypt(text, user_id):
137
  )
138
 
139
 
140
-
141
  def run_fhe(user_id):
142
  encoded_data_path = Path(f"tmp/tmp_encrypted_quantized_encoding_{user_id}.npy")
143
  if not user_id:
@@ -159,10 +119,9 @@ def run_fhe(user_id):
159
  query["evaluation_key"] = encoded_evaluation_key
160
  query["encrypted_encoding"] = encrypted_quantized_encoding
161
  headers = {"Content-type": "application/json"}
162
-
163
  response = requests.post(
164
- "http://localhost:8000/predict_sentiment", data=json.dumps(query), headers=headers
165
- )
166
  encrypted_prediction = base64.b64decode(response.json()["encrypted_prediction"])
167
 
168
  # Save encrypted_prediction in a file, since too large to pass through regular Gradio
@@ -183,9 +142,6 @@ def decrypt_prediction(user_id):
183
  # Read encrypted_prediction from the file
184
  encrypted_prediction = numpy.load(encoded_data_path).tobytes()
185
 
186
- if "legal_rating" in model_names:
187
- fhe_api = FHEModelClient(FHE_LEGAL_PATH, f".fhe_keys/{user_id}")
188
-
189
  fhe_api = FHEModelClient(FHE_MODEL_PATH, f".fhe_keys/{user_id}")
190
  fhe_api.load()
191
 
@@ -193,12 +149,10 @@ def decrypt_prediction(user_id):
193
  fhe_api.generate_private_and_evaluation_keys(force=False)
194
 
195
  predictions = fhe_api.deserialize_decrypt_dequantize(encrypted_prediction)
196
- print(predictions)
197
-
198
  return {
199
- "low_relative": predictions[0][0],
200
- "medium_relative": predictions[0][1],
201
- "high_relative": predictions[0][2],
202
  }
203
 
204
 
@@ -210,12 +164,22 @@ with demo:
210
 
211
  gr.Markdown(
212
  """
213
-
214
- <h2 align="center">📄Cipher Clause</h2>
215
- <p align="center">
216
- <img width=200 src="https://www.helloimg.com/i/2024/09/28/66f7f6701bcfb.jpeg">
217
- </p>
218
-
 
 
 
 
 
 
 
 
 
 
219
  """
220
  )
221
 
@@ -236,24 +200,10 @@ with demo:
236
  - The evaluation key is a public key that the server needs to process encrypted data.
237
  """
238
  )
239
- gr.Markdown(
240
- """
241
- <hr/>
242
- """
243
- )
244
- gr.Markdown("# Step 0: Select Task")
245
- task_checkbox = gr.CheckboxGroup(
246
- choices=["legal_rating", "financial_rating"],
247
- label="select_tasks"
248
- )
249
- gr.Markdown(
250
- """
251
- <hr/>
252
- """
253
- )
254
  gr.Markdown("# Step 1: Generate the keys")
255
 
256
- b_gen_key_and_install = gr.Button("Generate all the keys and send public part to server")
257
 
258
  evaluation_key = gr.Textbox(
259
  label="Evaluation key (truncated):",
@@ -267,46 +217,34 @@ with demo:
267
  interactive=False,
268
  visible=False
269
  )
270
- gr.Markdown(
271
- """
272
- <hr/>
273
- """
274
- )
275
- gr.Markdown("# Step 2: Provide a contract or clause")
276
  gr.Markdown("## Client side")
277
  gr.Markdown(
278
- "Enter a contract or clause you want to analysis)."
279
- )
280
- text = gr.Textbox(label="Enter some words:", value="The Employee is entitled to two weeks of paid vacation annually, to be scheduled at the mutual convenience of the Employee and Employer.")
281
- gr.Markdown(
282
- """
283
- <hr/>
284
- """
285
  )
 
 
286
  gr.Markdown("# Step 3: Encode the message with the private key")
287
  b_encode_quantize_text = gr.Button(
288
- "Encode, quantize and encrypt the text with vectorizer, and send to server"
289
  )
290
 
291
  with gr.Row():
292
  encoding = gr.Textbox(
293
- label="Representation:",
294
  max_lines=4,
295
  interactive=False,
296
  )
297
  quantized_encoding = gr.Textbox(
298
- label="Quantized representation:", max_lines=4, interactive=False
299
  )
300
  encrypted_quantized_encoding = gr.Textbox(
301
- label="Encrypted quantized representation (truncated):",
302
  max_lines=4,
303
  interactive=False,
304
  )
305
- gr.Markdown(
306
- """
307
- <hr/>
308
- """
309
- )
310
  gr.Markdown("# Step 4: Run the FHE evaluation")
311
  gr.Markdown("## Server side")
312
  gr.Markdown(
@@ -319,22 +257,18 @@ with demo:
319
  max_lines=4,
320
  interactive=False,
321
  )
322
- gr.Markdown(
323
- """
324
- <hr/>
325
- """
326
- )
327
- gr.Markdown("# Step 5: Decrypt the class")
328
  gr.Markdown("## Client side")
329
  gr.Markdown(
330
  "The encrypted sentiment is sent back to client, who can finally decrypt it with its private key. Only the client is aware of the original tweet and the prediction."
331
  )
332
  b_decrypt_prediction = gr.Button("Decrypt prediction")
333
 
334
- labels_sentiment = gr.Label(label="level:")
335
 
336
  # Button for key generation
337
- b_gen_key_and_install.click(keygen, inputs=[task_checkbox], outputs=[evaluation_key, user_id])
338
 
339
  # Button to quantize and encrypt
340
  b_encode_quantize_text.click(
 
1
  import gradio as gr
2
  from requests import head
3
  from transformer_vectorizer import TransformerVectorizer
 
 
4
  from concrete.ml.deployment import FHEModelClient
5
  import numpy
6
  import os
 
24
  # (encrypted data is too large to display in the browser)
25
  ENCRYPTED_DATA_BROWSER_LIMIT = 500
26
  N_USER_KEY_STORED = 20
 
 
 
27
  FHE_MODEL_PATH = "deployment/financial_rating"
 
 
28
 
29
  print("Loading the transformer model...")
30
 
31
  # Initialize the transformer vectorizer
32
  transformer_vectorizer = TransformerVectorizer()
 
33
 
34
  def clean_tmp_directory():
35
  # Allow 20 user keys to be stored.
 
49
  for user_id in user_ids:
50
  if file.name.endswith(f"{user_id}.npy"):
51
  file.unlink()
 
52
 
53
+
54
+ def keygen():
55
  # Clean tmp directory if needed
56
  clean_tmp_directory()
57
 
58
  print("Initializing FHEModelClient...")
59
 
60
+ # Let's create a user_id
 
 
 
61
  user_id = numpy.random.randint(0, 2**32)
62
+ fhe_api = FHEModelClient(FHE_MODEL_PATH, f".fhe_keys/{user_id}")
63
+ fhe_api.load()
 
 
 
 
64
 
 
 
65
 
66
+ # Generate a fresh key
 
 
 
 
 
 
 
 
67
  fhe_api.generate_private_and_evaluation_keys(force=True)
68
  evaluation_key = fhe_api.get_serialized_evaluation_keys()
69
+
70
+ # Save evaluation_key in a file, since too large to pass through regular Gradio
71
+ # buttons, https://github.com/gradio-app/gradio/issues/1877
72
  numpy.save(f"tmp/tmp_evaluation_key_{user_id}.npy", evaluation_key)
73
 
74
  return [list(evaluation_key)[:ENCRYPTED_DATA_BROWSER_LIMIT], user_id]
75
 
76
 
 
 
 
77
  def encode_quantize_encrypt(text, user_id):
78
  if not user_id:
79
  raise gr.Error("You need to generate FHE keys first.")
80
+
81
+ fhe_api = FHEModelClient(FHE_MODEL_PATH, f".fhe_keys/{user_id}")
 
 
 
 
 
 
 
 
 
 
 
 
82
  fhe_api.load()
83
+ encodings = transformer_vectorizer.transform([text])
84
  quantized_encodings = fhe_api.model.quantize_input(encodings).astype(numpy.uint8)
85
  encrypted_quantized_encoding = fhe_api.quantize_encrypt_serialize(encodings)
86
 
 
98
  )
99
 
100
 
 
101
  def run_fhe(user_id):
102
  encoded_data_path = Path(f"tmp/tmp_encrypted_quantized_encoding_{user_id}.npy")
103
  if not user_id:
 
119
  query["evaluation_key"] = encoded_evaluation_key
120
  query["encrypted_encoding"] = encrypted_quantized_encoding
121
  headers = {"Content-type": "application/json"}
 
122
  response = requests.post(
123
+ "http://localhost:8000/predict_sentiment", data=json.dumps(query), headers=headers
124
+ )
125
  encrypted_prediction = base64.b64decode(response.json()["encrypted_prediction"])
126
 
127
  # Save encrypted_prediction in a file, since too large to pass through regular Gradio
 
142
  # Read encrypted_prediction from the file
143
  encrypted_prediction = numpy.load(encoded_data_path).tobytes()
144
 
 
 
 
145
  fhe_api = FHEModelClient(FHE_MODEL_PATH, f".fhe_keys/{user_id}")
146
  fhe_api.load()
147
 
 
149
  fhe_api.generate_private_and_evaluation_keys(force=False)
150
 
151
  predictions = fhe_api.deserialize_decrypt_dequantize(encrypted_prediction)
 
 
152
  return {
153
+ "negative": predictions[0][0],
154
+ "neutral": predictions[0][1],
155
+ "positive": predictions[0][2],
156
  }
157
 
158
 
 
164
 
165
  gr.Markdown(
166
  """
167
+ <p align="center">
168
+ <img width=200 src="https://user-images.githubusercontent.com/5758427/197816413-d9cddad3-ba38-4793-847d-120975e1da11.png">
169
+ </p>
170
+ <h2 align="center">Sentiment Analysis On Encrypted Data Using Homomorphic Encryption</h2>
171
+ <p align="center">
172
+ <a href="https://github.com/zama-ai/concrete-ml"> <img style="vertical-align: middle; display:inline-block; margin-right: 3px;" width=15 src="https://user-images.githubusercontent.com/5758427/197972109-faaaff3e-10e2-4ab6-80f5-7531f7cfb08f.png">Concrete-ML</a>
173
+
174
+ <a href="https://docs.zama.ai/concrete-ml"> <img style="vertical-align: middle; display:inline-block; margin-right: 3px;" width=15 src="https://user-images.githubusercontent.com/5758427/197976802-fddd34c5-f59a-48d0-9bff-7ad1b00cb1fb.png">Documentation</a>
175
+
176
+ <a href="https://zama.ai/community"> <img style="vertical-align: middle; display:inline-block; margin-right: 3px;" width=15 src="https://user-images.githubusercontent.com/5758427/197977153-8c9c01a7-451a-4993-8e10-5a6ed5343d02.png">Community</a>
177
+
178
+ <a href="https://twitter.com/zama_fhe"> <img style="vertical-align: middle; display:inline-block; margin-right: 3px;" width=15 src="https://user-images.githubusercontent.com/5758427/197975044-bab9d199-e120-433b-b3be-abd73b211a54.png">@zama_fhe</a>
179
+ </p>
180
+ <p align="center">
181
+ <img src="https://user-images.githubusercontent.com/56846628/219329304-6868be9e-5ce8-4279-9123-4cb1bc0c2fb5.png" width="60%" height="60%">
182
+ </p>
183
  """
184
  )
185
 
 
200
  - The evaluation key is a public key that the server needs to process encrypted data.
201
  """
202
  )
203
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204
  gr.Markdown("# Step 1: Generate the keys")
205
 
206
+ b_gen_key_and_install = gr.Button("Generate the keys and send public part to server")
207
 
208
  evaluation_key = gr.Textbox(
209
  label="Evaluation key (truncated):",
 
217
  interactive=False,
218
  visible=False
219
  )
220
+
221
+ gr.Markdown("# Step 2: Provide a message")
 
 
 
 
222
  gr.Markdown("## Client side")
223
  gr.Markdown(
224
+ "Enter a sensitive text message you received and would like to do sentiment analysis on (ideas: the last text message of your boss.... or lover)."
 
 
 
 
 
 
225
  )
226
+ text = gr.Textbox(label="Enter a message:", value="I really like your work recently")
227
+
228
  gr.Markdown("# Step 3: Encode the message with the private key")
229
  b_encode_quantize_text = gr.Button(
230
+ "Encode, quantize and encrypt the text with transformer vectorizer, and send to server"
231
  )
232
 
233
  with gr.Row():
234
  encoding = gr.Textbox(
235
+ label="Transformer representation:",
236
  max_lines=4,
237
  interactive=False,
238
  )
239
  quantized_encoding = gr.Textbox(
240
+ label="Quantized transformer representation:", max_lines=4, interactive=False
241
  )
242
  encrypted_quantized_encoding = gr.Textbox(
243
+ label="Encrypted quantized transformer representation (truncated):",
244
  max_lines=4,
245
  interactive=False,
246
  )
247
+
 
 
 
 
248
  gr.Markdown("# Step 4: Run the FHE evaluation")
249
  gr.Markdown("## Server side")
250
  gr.Markdown(
 
257
  max_lines=4,
258
  interactive=False,
259
  )
260
+
261
+ gr.Markdown("# Step 5: Decrypt the sentiment")
 
 
 
 
262
  gr.Markdown("## Client side")
263
  gr.Markdown(
264
  "The encrypted sentiment is sent back to client, who can finally decrypt it with its private key. Only the client is aware of the original tweet and the prediction."
265
  )
266
  b_decrypt_prediction = gr.Button("Decrypt prediction")
267
 
268
+ labels_sentiment = gr.Label(label="Sentiment:")
269
 
270
  # Button for key generation
271
+ b_gen_key_and_install.click(keygen, inputs=[], outputs=[evaluation_key, user_id])
272
 
273
  # Button to quantize and encrypt
274
  b_encode_quantize_text.click(