mirror of
https://github.com/luxfhe/ml-sdk.git
synced 2026-10-30 18:13:04 +00:00
Brand-only sweep. Touches READMEs, docs, package metadata, comments,
notebook markdown, requirements.txt files; does NOT yet touch Python
`concrete.*` imports (those are module-level dependencies requiring the
phase-2 Python module port from `concrete` → `torus`).
Substitutions applied:
Concrete ML → TorusML
concrete-ml → torus-ml
Concrete-ML → Torus-ML
concrete_ml → torus_ml
zama-ai/concrete-ml → luxfhe/ml-sdk
zama-ai/concrete → luxfhe/torus
github.com/zama-ai → github.com/luxfhe
docs.zama.ai/concrete-ml → docs.luxfhe.com/ml-sdk
docs.zama.ai/concrete → docs.luxfhe.com/torus
Zama Concrete ML → Lux TorusML
Zama Concrete → Lux Torus
Zama tfhe-rs / Zama TFHE-rs → Lux-FHE
tfhe-rs / TFHE-rs → Lux-FHE
Zama fhEVM / fhEVM → TorusEVM
Concrete framework → Torus framework
Concrete compiler → Torus compiler
Concrete by Zama → Torus by Lux
the Zama team → the Lux Industries team
Zama's → Lux Industries'
(Zama) → (Lux)
CoFHE / Fhenix → (removed)
LICENSE: original Zama copyright RETAINED per BSD-3-Clause-Clear §1-§2
requirements; Lux Industries modifications copyright added. Per §3 no
name of ZAMA used to endorse the derived work — product marketed
exclusively as TorusML.
README image URLs migrated to github.com/luxfhe/ml-sdk/assets to break
the dependency on Zama's CDN.
Hit count: 350 → 295. Residual hits are Python `from concrete.fhe import`
imports referencing the upstream Zama `concrete` PyPI package; these
require module-level port (phase 2):
Phase 2 plan:
1. Fork zama-ai/concrete (the Python compiler) to luxfhe/torus
2. Rename Python module `concrete` → `torus`; PyPI publish as `torus-fhe`
3. Update ml-sdk imports from `concrete.fhe` → `torus.fhe`, etc.
4. Wire `torus.compiler` GPU dispatch through `luxcpp/gpu` vtbl
(lux-private/gpu-kernels for CUDA/Metal/WebGPU/FPGA targets)
5. Port concrete-cuda + concrete-mlir kernels to
lux-private/gpu-kernels/{cuda,metal,wgsl}/ckks/ (matrix-vector
mul, rescale, rotate, bootstrap for TorusML inference)
Phase 3 plan (kernels):
- CKKS/BGV/BFV GPU kernels in lux-private/gpu-kernels/
(currently only TFHE PBS / keyswitch / blind-rotate exist)
- FPGA bitstreams in lux-private/fpga/ (currently scaffold only)
Phase 1 = docs/branding sweep. PR not opened; user reviews and merges.
105 lines
3.5 KiB
Python
105 lines
3.5 KiB
Python
import matplotlib.pyplot as plt
|
|
import numpy as np
|
|
from matplotlib.colors import ListedColormap
|
|
from sklearn.metrics import accuracy_score
|
|
|
|
# pylint: disable=too-many-locals
|
|
def plot_data(axs, X_train, y_train, X_test, y_test, model, name, h=0.04, font_size_text=20):
|
|
# Train the model and retrieve both the TorusML model and its equivalent one from
|
|
# scikit-learn
|
|
concrete_model, sklearn_model = model.fit_benchmark(X_train, y_train)
|
|
|
|
# Compute the predictions in clear using the scikit-learn model
|
|
sklearn_y_pred = sklearn_model.predict(X_test)
|
|
|
|
# Compile the TorusML model
|
|
circuit = concrete_model.compile(X_test)
|
|
concrete_y_pred = concrete_model.predict(X_test, fhe="simulate")
|
|
|
|
# Measure the accuracy scores
|
|
sklearn_score = accuracy_score(sklearn_y_pred, y_test)
|
|
concrete_score = accuracy_score(concrete_y_pred, y_test)
|
|
|
|
bitwidth = circuit.graph.maximum_integer_bit_width()
|
|
|
|
x_min, x_max = X_test[:, 0].min() - 0.5, X_test[:, 0].max() + 0.5
|
|
y_min, y_max = X_test[:, 1].min() - 0.5, X_test[:, 1].max() + 0.5
|
|
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
|
|
|
|
# pylint: disable-next=no-member
|
|
cm = plt.cm.RdBu
|
|
cm_bright = ListedColormap(["#FF0000", "#0000FF"])
|
|
|
|
raveled_input = np.c_[xx.ravel(), yy.ravel()]
|
|
|
|
# Plot the decision boundaries.
|
|
# For that, a color is assigned to each point in the mesh, which is obtained as a
|
|
# cartesian product of [x_min, x_max] with [y_min, y_max].
|
|
if hasattr(sklearn_model, "decision_function"):
|
|
sklearn_Z = sklearn_model.decision_function(raveled_input)
|
|
concrete_Z = concrete_model.decision_function(raveled_input, fhe="simulate")
|
|
else:
|
|
sklearn_Z = sklearn_model.predict_proba(raveled_input.astype(np.float32))[:, 1]
|
|
concrete_Z = concrete_model.predict_proba(raveled_input, fhe="simulate")[:, 1]
|
|
|
|
for _, (ax, framework, score, Z) in enumerate(
|
|
zip(
|
|
axs,
|
|
["scikit-learn", "TorusML"],
|
|
[sklearn_score, concrete_score],
|
|
[sklearn_Z, concrete_Z],
|
|
)
|
|
):
|
|
|
|
# Put the result into a color plot
|
|
Z = Z.reshape(xx.shape)
|
|
ax.contourf(xx, yy, Z, cmap=cm, alpha=0.8)
|
|
|
|
# Plot the training points
|
|
ax.scatter(X_test[:, 0], X_test[:, 1], c=y_test, cmap=cm_bright, edgecolors="k")
|
|
|
|
# Plot the testing points
|
|
ax.scatter(
|
|
X_test[:, 0],
|
|
X_test[:, 1],
|
|
c=y_test,
|
|
marker="D",
|
|
cmap=cm_bright,
|
|
edgecolors="k",
|
|
alpha=0.6,
|
|
)
|
|
|
|
ax.contour(
|
|
xx,
|
|
yy,
|
|
Z,
|
|
levels=[0.5],
|
|
linewidths=2,
|
|
)
|
|
|
|
ax.set_xlim(xx.min(), xx.max())
|
|
ax.set_ylim(yy.min(), yy.max())
|
|
ax.tick_params(axis='x', labelsize=font_size_text)
|
|
ax.tick_params(axis='y', labelsize=font_size_text)
|
|
|
|
ax.set_title(
|
|
f"Logistic Regression ({framework}) with {name} data.", fontsize=font_size_text
|
|
)
|
|
|
|
ax.text(
|
|
xx.max() - 0.3,
|
|
yy.min() + 0.3,
|
|
f"{score*100:0.1f}%",
|
|
size=font_size_text,
|
|
horizontalalignment="right",
|
|
)
|
|
|
|
if bitwidth and framework == "TorusML":
|
|
ax.text(
|
|
xx.max() - 0.3,
|
|
yy.min() + 1.0,
|
|
f"bit-width={bitwidth}",
|
|
size=font_size_text,
|
|
horizontalalignment="right",
|
|
)
|