romanbredehoft-zama
commited on
Commit
β’
1ad0c1c
1
Parent(s):
74c0c8e
Merge step 5 & 6
Browse files- app.py +9 -26
- backend.py +19 -46
app.py
CHANGED
@@ -24,8 +24,7 @@ from backend import (
|
|
24 |
pre_process_encrypt_send_bank,
|
25 |
pre_process_encrypt_send_third_party,
|
26 |
run_fhe,
|
27 |
-
|
28 |
-
decrypt_output,
|
29 |
years_employed_encrypt_run_decrypt,
|
30 |
)
|
31 |
|
@@ -85,7 +84,7 @@ with demo:
|
|
85 |
gr.Markdown("### User")
|
86 |
bool_inputs = gr.CheckboxGroup(["Car", "Property", "Mobile phone"], label="Which of the following do you actively hold or own?")
|
87 |
num_children = gr.Slider(**CHILDREN_MIN_MAX, step=1, label="Number of children", info="How many children do you have ?")
|
88 |
-
household_size = gr.Slider(**FAMILY_MIN_MAX, step=1, label="Household size", info="How many members does your household have
|
89 |
total_income = gr.Slider(**INCOME_MIN_MAX, label="Income", info="What's you total yearly income (in euros) ?")
|
90 |
age = gr.Slider(**AGE_MIN_MAX, step=1, label="Age", info="How old are you ?")
|
91 |
income_type = gr.Dropdown(choices=INCOME_TYPES, value=INCOME_TYPES[0], label="Income type", info="What is your main type of income ?")
|
@@ -184,7 +183,7 @@ with demo:
|
|
184 |
"""
|
185 |
)
|
186 |
|
187 |
-
gr.Markdown("## Step 5: Receive the encrypted output from the server.")
|
188 |
gr.Markdown(
|
189 |
"""
|
190 |
The value displayed below is a shortened byte representation of the actual encrypted output.
|
@@ -195,34 +194,18 @@ with demo:
|
|
195 |
encrypted_output_representation = gr.Textbox(
|
196 |
label="Encrypted output representation: ", max_lines=2, interactive=False
|
197 |
)
|
198 |
-
|
199 |
-
# Button to send the encodings to the server using post method
|
200 |
-
get_output_button.click(
|
201 |
-
get_output,
|
202 |
-
inputs=[client_id],
|
203 |
-
outputs=[encrypted_output_representation],
|
204 |
-
)
|
205 |
-
|
206 |
-
gr.Markdown("## Step 6: Decrypt the output.")
|
207 |
-
gr.Markdown(
|
208 |
-
"""
|
209 |
-
The user is able to decrypt the prediction using its private key.
|
210 |
-
"""
|
211 |
-
)
|
212 |
-
|
213 |
-
decrypt_button = gr.Button("Decrypt the output")
|
214 |
prediction_output = gr.Textbox(
|
215 |
label="Prediction", max_lines=1, interactive=False
|
216 |
)
|
217 |
|
218 |
-
# Button to
|
219 |
-
|
220 |
-
|
221 |
-
inputs=[client_id],
|
222 |
-
outputs=[prediction_output],
|
223 |
)
|
224 |
|
225 |
-
gr.Markdown("## Step
|
226 |
gr.Markdown(
|
227 |
"""
|
228 |
In case the credit card is likely to be denied, the user can run a second model in order to
|
|
|
24 |
pre_process_encrypt_send_bank,
|
25 |
pre_process_encrypt_send_third_party,
|
26 |
run_fhe,
|
27 |
+
get_output_and_decrypt,
|
|
|
28 |
years_employed_encrypt_run_decrypt,
|
29 |
)
|
30 |
|
|
|
84 |
gr.Markdown("### User")
|
85 |
bool_inputs = gr.CheckboxGroup(["Car", "Property", "Mobile phone"], label="Which of the following do you actively hold or own?")
|
86 |
num_children = gr.Slider(**CHILDREN_MIN_MAX, step=1, label="Number of children", info="How many children do you have ?")
|
87 |
+
household_size = gr.Slider(**FAMILY_MIN_MAX, step=1, label="Household size", info="How many members does your household have ?")
|
88 |
total_income = gr.Slider(**INCOME_MIN_MAX, label="Income", info="What's you total yearly income (in euros) ?")
|
89 |
age = gr.Slider(**AGE_MIN_MAX, step=1, label="Age", info="How old are you ?")
|
90 |
income_type = gr.Dropdown(choices=INCOME_TYPES, value=INCOME_TYPES[0], label="Income type", info="What is your main type of income ?")
|
|
|
183 |
"""
|
184 |
)
|
185 |
|
186 |
+
gr.Markdown("## Step 5: Receive the encrypted output from the server and decrypt.")
|
187 |
gr.Markdown(
|
188 |
"""
|
189 |
The value displayed below is a shortened byte representation of the actual encrypted output.
|
|
|
194 |
encrypted_output_representation = gr.Textbox(
|
195 |
label="Encrypted output representation: ", max_lines=2, interactive=False
|
196 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
197 |
prediction_output = gr.Textbox(
|
198 |
label="Prediction", max_lines=1, interactive=False
|
199 |
)
|
200 |
|
201 |
+
# Button to send the encodings to the server using post method
|
202 |
+
get_output_button.click(
|
203 |
+
get_output_and_decrypt,
|
204 |
+
inputs=[client_id],
|
205 |
+
outputs=[prediction_output, encrypted_output_representation],
|
206 |
)
|
207 |
|
208 |
+
gr.Markdown("## Step 6 (optional): Explain the prediction.")
|
209 |
gr.Markdown(
|
210 |
"""
|
211 |
In case the credit card is likely to be denied, the user can run a second model in order to
|
backend.py
CHANGED
@@ -410,14 +410,15 @@ def run_fhe(client_id):
|
|
410 |
raise gr.Error("Please send the inputs from all three parties to the server first.")
|
411 |
|
412 |
|
413 |
-
def
|
414 |
"""Retrieve the encrypted output.
|
415 |
|
416 |
Args:
|
417 |
client_id (str): The current client ID to consider.
|
418 |
|
419 |
Returns:
|
420 |
-
|
|
|
421 |
"""
|
422 |
|
423 |
if client_id == "":
|
@@ -434,56 +435,28 @@ def get_output(client_id):
|
|
434 |
data=data,
|
435 |
) as response:
|
436 |
if response.ok:
|
437 |
-
|
438 |
-
|
439 |
-
# Save the encrypted output to bytes in a file as it is too large to pass through regular
|
440 |
-
# Gradio buttons (see https://github.com/gradio-app/gradio/issues/1877)
|
441 |
-
encrypted_output_path = _get_client_file_path("encrypted_output", client_id)
|
442 |
-
|
443 |
-
with encrypted_output_path.open("wb") as encrypted_output_file:
|
444 |
-
encrypted_output_file.write(encrypted_output)
|
445 |
|
446 |
# Create a truncated version of the encrypted inputs for display
|
447 |
-
encrypted_output_short = shorten_bytes_object(
|
448 |
-
|
449 |
-
return encrypted_output_short
|
450 |
-
else:
|
451 |
-
raise gr.Error("Please run the FHE execution first and wait for it to be completed.")
|
452 |
-
|
453 |
|
454 |
-
|
455 |
-
|
456 |
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
Returns:
|
461 |
-
output(numpy.ndarray): The decrypted output
|
462 |
-
"""
|
463 |
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
# Load the encrypted output as bytes
|
474 |
-
with encrypted_output_path.open("rb") as encrypted_output_file:
|
475 |
-
encrypted_output_proba = encrypted_output_file.read()
|
476 |
-
|
477 |
-
# Retrieve the client API
|
478 |
-
client = _get_client(client_id)
|
479 |
-
|
480 |
-
# Deserialize, decrypt and post-process the encrypted output
|
481 |
-
output_proba = client.deserialize_decrypt_dequantize(encrypted_output_proba)
|
482 |
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
return "Credit card is likely to be approved β
" if output == 1 else "Credit card is likely to be denied β"
|
487 |
|
488 |
|
489 |
def years_employed_encrypt_run_decrypt(client_id, prediction_output, *inputs):
|
|
|
410 |
raise gr.Error("Please send the inputs from all three parties to the server first.")
|
411 |
|
412 |
|
413 |
+
def get_output_and_decrypt(client_id):
|
414 |
"""Retrieve the encrypted output.
|
415 |
|
416 |
Args:
|
417 |
client_id (str): The current client ID to consider.
|
418 |
|
419 |
Returns:
|
420 |
+
(Tuple[str, bytes]): The output message based on the decrypted prediction as well as
|
421 |
+
a byte short representation of the encrypted output.
|
422 |
"""
|
423 |
|
424 |
if client_id == "":
|
|
|
435 |
data=data,
|
436 |
) as response:
|
437 |
if response.ok:
|
438 |
+
encrypted_output_proba = response.content
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
439 |
|
440 |
# Create a truncated version of the encrypted inputs for display
|
441 |
+
encrypted_output_short = shorten_bytes_object(encrypted_output_proba)
|
|
|
|
|
|
|
|
|
|
|
442 |
|
443 |
+
# Retrieve the client API
|
444 |
+
client = _get_client(client_id)
|
445 |
|
446 |
+
# Deserialize, decrypt and post-process the encrypted output
|
447 |
+
output_proba = client.deserialize_decrypt_dequantize(encrypted_output_proba)
|
|
|
|
|
|
|
|
|
448 |
|
449 |
+
# Determine the predicted class
|
450 |
+
output = numpy.argmax(output_proba, axis=1).squeeze()
|
451 |
+
|
452 |
+
return (
|
453 |
+
"Credit card is likely to be approved β
" if output == 1
|
454 |
+
else "Credit card is likely to be denied β",
|
455 |
+
encrypted_output_short,
|
456 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
457 |
|
458 |
+
else:
|
459 |
+
raise gr.Error("Please run the FHE execution first and wait for it to be completed.")
|
|
|
|
|
460 |
|
461 |
|
462 |
def years_employed_encrypt_run_decrypt(client_id, prediction_output, *inputs):
|