diff --git a/include/aidge/backend/cpu/data/TensorImpl.hpp b/include/aidge/backend/cpu/data/TensorImpl.hpp
index 9390fe5860b5d3523886856d9b2a40752d338af5..5f4e257720bda050086f1bc17b240b410c1c8341 100644
--- a/include/aidge/backend/cpu/data/TensorImpl.hpp
+++ b/include/aidge/backend/cpu/data/TensorImpl.hpp
@@ -126,6 +126,7 @@ REGISTRAR(Tensor, {"cpu", DataType::Int64}, Aidge::TensorImpl_cpu<int64_t>::crea
 REGISTRAR(Tensor, {"cpu", DataType::Int32}, Aidge::TensorImpl_cpu<int32_t>::create);
 REGISTRAR(Tensor, {"cpu", DataType::Int16}, Aidge::TensorImpl_cpu<int16_t>::create);
 REGISTRAR(Tensor, {"cpu", DataType::Int8}, Aidge::TensorImpl_cpu<int8_t>::create);
+REGISTRAR(Tensor, {"cpu", DataType::Int4}, Aidge::TensorImpl_cpu<int8_t>::create);
 REGISTRAR(Tensor, {"cpu", DataType::UInt64}, Aidge::TensorImpl_cpu<uint64_t>::create);
 REGISTRAR(Tensor, {"cpu", DataType::UInt32}, Aidge::TensorImpl_cpu<uint32_t>::create);
 REGISTRAR(Tensor, {"cpu", DataType::UInt16}, Aidge::TensorImpl_cpu<uint16_t>::create);
diff --git a/include/aidge/data/Data.hpp b/include/aidge/data/Data.hpp
index 6f877194252c7145ea61e1105e0edb0080409d46..c69305d84aad4219816ceb7792e12c80de0e2d1c 100644
--- a/include/aidge/data/Data.hpp
+++ b/include/aidge/data/Data.hpp
@@ -104,10 +104,17 @@ private:
 }
 
 namespace {
+
+// Define a distinct type alias for Int4
+struct Int4Type {
+    std::int8_t value;
+};
+
 template <typename T> struct NativeType { static const Aidge::DataType type; };
 template <> const Aidge::DataType NativeType<double>::type = Aidge::DataType::Float64;
 template <> const Aidge::DataType NativeType<float>::type = Aidge::DataType::Float32;
 template <> const Aidge::DataType NativeType<half_float::half>::type = Aidge::DataType::Float16;
+template <> const Aidge::DataType NativeType<Int4Type>::type = Aidge::DataType::Int4;
 template <> const Aidge::DataType NativeType<std::int8_t>::type = Aidge::DataType::Int8;
 template <> const Aidge::DataType NativeType<std::int16_t>::type = Aidge::DataType::Int16;
 template <> const Aidge::DataType NativeType<std::int32_t>::type = Aidge::DataType::Int32;
@@ -134,6 +141,7 @@ template <Aidge::DataType D> struct cpptype {
 template <> struct cpptype<Aidge::DataType::Float16> { using type = half_float::half; };
 template <> struct cpptype<Aidge::DataType::Float32> { using type = float; };
 template <> struct cpptype<Aidge::DataType::Float64> { using type = double; };
+template <> struct cpptype<Aidge::DataType::Int4> { using type = Int4Type; };
 template <> struct cpptype<Aidge::DataType::Int8> { using type = std::int8_t; };
 template <> struct cpptype<Aidge::DataType::Int16> { using type = std::int16_t; };
 template <> struct cpptype<Aidge::DataType::Int32> { using type = std::int32_t; };
@@ -144,6 +152,9 @@ template <> struct cpptype<Aidge::DataType::UInt32> { using type = std::uint32_t
 template <> struct cpptype<Aidge::DataType::UInt64> { using type = std::uint64_t; };
 
 template <Aidge::DataType D> using cpptype_t = typename cpptype<D>::type;
+
+
+
 }
 
 
diff --git a/python_binding/data/pybind_Tensor.cpp b/python_binding/data/pybind_Tensor.cpp
index b972c87dcda8f912ff40feef0001b95d5feac71e..52b8021a3c105486e5cbdf382bdc255cea9406dc 100644
--- a/python_binding/data/pybind_Tensor.cpp
+++ b/python_binding/data/pybind_Tensor.cpp
@@ -226,6 +226,8 @@ static T castToNativeType(const py::object val_obj) {
     DataType dtype;
     getConservativeNativeVal(val_obj, &val, &dtype);
     switch (dtype) {
+    case DataType::Int4:
+        return (T)val.i8;
     case DataType::Int8:
         return (T)val.i8;
     case DataType::Int16:
@@ -497,6 +499,9 @@ void init_Tensor(py::module& m){
             case DataType::Float32:
                 dataFormatDescriptor = py::format_descriptor<float>::format();
                 break;;
+            case DataType::Int4:
+                dataFormatDescriptor = py::format_descriptor<std::int8_t>::format();
+                break;
             case DataType::Int8:
                 dataFormatDescriptor = py::format_descriptor<std::int8_t>::format();
                 break;
diff --git a/src/data/Tensor.cpp b/src/data/Tensor.cpp
index 3dcdcc65d0ef40b0443eb5b9662111420ce4fb86..bc1de946aa78b629ef895029f7542031200af50d 100644
--- a/src/data/Tensor.cpp
+++ b/src/data/Tensor.cpp
@@ -250,6 +250,8 @@ std::string Aidge::Tensor::toString() const {
                 return std::to_string(static_cast<float*>(ptr)[idx]);
             case DataType::Float16:
                 return std::to_string(static_cast<half_float::half*>(ptr)[idx]);
+            case DataType::Int4:
+                return std::to_string(static_cast<int8_t*>(ptr)[idx]);
             case DataType::Int8:
                 return std::to_string(static_cast<int8_t*>(ptr)[idx]);
             case DataType::Int16: