Hello
Answering when the rest of the people is off here.
I could check the code of the SGDClassifier, and pretty clear that the method fit() is implemented to receive plaintext and encrypt it.
I am not sure why you believe this. You have
# If the model should be trained using FHE training
if self.fit_encrypted:
if fhe is None:
fhe = "disable"
warnings.warn(
"Parameter 'fhe' isn't set while FHE training is enabled.\n"
f"Defaulting to '{fhe=}'",
stacklevel=2,
)
# Make sure the `fhe` parameter is correct
assert FheMode.is_valid(fhe), (
"`fhe` mode is not supported. Expected one of 'disable' (resp. FheMode.DISABLE), "
"'simulate' (resp. FheMode.SIMULATE) or 'execute' (resp. FheMode.EXECUTE). Got "
f"{fhe}",
)
if sample_weight is not None:
raise NotImplementedError(
"Parameter 'sample_weight' is currently not supported for FHE training."
)
return self._fit_encrypted(
X=X,
y=y,
fhe=fhe,
coef_init=coef_init,
intercept_init=intercept_init,
)
and _fit_encrypted is really an FHE training. But, as Celia explained, the encryption in this function is made inside _fit_encrypted. I am not the code writer or owner, but I see
# The underlying quantized module expects (X, y, weight, bias) as inputs. We thus only
# quantize the input and target values using the first and second positional parameter
q_X_batch, q_y_batch, _, _ = self.training_quantized_module.quantize_input(
X_batch, y_batch, None, None
)
# If the training is done in FHE, encrypt the input and target values
if fhe == "execute":
# Similarly, the underlying FHE circuit expects (X, y, weight, bias) as inputs, and
# so does the encrypt method
X_batch_enc, y_batch_enc, _, _ = self.training_quantized_module.fhe_circuit.encrypt(
q_X_batch, q_y_batch, None, None
)
else:
X_batch_enc, y_batch_enc = q_X_batch, q_y_batch
X_batches_enc.append(X_batch_enc)
y_batches_enc.append(y_batch_enc)
That’s why Celia told you to have a look to
fhe_client.get_serialized_evaluation_keys()
fhe_client.quantize_encrypt_serialize
fhe_server.run
fhe_client.deserialize_decrypt_dequantize
Here, when you deploy, you’ll be able to use fhe_server.run
, which does exactly the FHE training on encrypted inputs. Remark that the output is also encrypted, and will be decrypted and dequantized only in fhe_client.deserialize_decrypt_dequantize
.
You can see _fit_encrypted as a packaged function which is mainly used for tests, which packs all the process, and when we deploy, we call the individual functions. That’s exactly as the
# Finally we run the inference on encrypted inputs !
y_pred_fhe = model.predict(X_test, fhe="execute")
that exists for inference: here as well, X_test is in the clear and inside, it will be encrypted. When we deploy this, we call the individual
# Quantize an original float input
q_input = model.quantize_input(X_test[[0]])
# Encrypt the input
q_input_enc = model.fhe_circuit.encrypt(q_input)
# Execute the linear product in FHE
q_y_enc = model.fhe_circuit.run(q_input_enc)
# Decrypt the result (integer)
q_y = model.fhe_circuit.decrypt(q_y_enc)
# De-quantize and post-process the result
y0 = model.post_processing(model.dequantize_output(q_y))
parts.
Remark that currently, only linear-model training is available in FHE; we are working on training for other kinds of models.
Yes FL is an interesting tech. If you want to speak more precisely of your use-case, don’t hesitate to go to https://www.zama.ai, in “Contact us”, and drop a message to say you want to speak to me, explaining a bit the context.
Cheers