Skip to content

Commit 9e4bf4a

Browse files
committed
docs: document NumPy-accelerated vector serialization
Add a new section to docs/performance.rst covering the three fast serialization paths (single-row ndarray, bulk serialize_numpy_bulk, bytes passthrough) with usage examples and supported subtype list.
1 parent 869b72f commit 9e4bf4a

1 file changed

Lines changed: 50 additions & 0 deletions

File tree

docs/performance.rst

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,53 @@ objects should all be created after forking the process, not before.
4343

4444
For further discussion and simple examples using the driver with ``multiprocessing``,
4545
see `this blog post <http://www.datastax.com/dev/blog/datastax-python-driver-multiprocessing-example-for-improved-bulk-data-throughput>`_.
46+
47+
NumPy-accelerated Vector Serialization
48+
--------------------------------------
49+
When inserting high-dimensional vectors (e.g. ML embeddings), the default
50+
element-by-element serialization in
51+
:class:`~cassandra.cqltypes.VectorType` can become a bottleneck. If
52+
`NumPy <https://numpy.org>`_ is installed, the driver provides three
53+
progressively faster paths:
54+
55+
**Single-row ndarray fast path** – pass a 1-D ``numpy.ndarray`` directly
56+
as the bound value for a ``vector<float, N>`` column. The driver
57+
byte-swaps the array to big-endian in a single C-level operation and
58+
calls ``tobytes()``, replacing *N* individual ``struct.pack`` calls::
59+
60+
import numpy as np
61+
embedding = np.array([0.1, 0.2, ..., 0.768], dtype=np.float32)
62+
session.execute(insert_stmt, [key, embedding])
63+
64+
**Bulk serialization** – for batch inserts, convert an entire 2-D array
65+
(one row per vector) into a list of ``bytes`` objects with a single
66+
byte-swap::
67+
68+
from cassandra.cqltypes import VectorType
69+
70+
# Build the parameterized type (usually done once)
71+
ctype = VectorType.apply_parameters(
72+
[lookup_casstype('org.apache.cassandra.db.marshal.FloatType'), 768],
73+
names=None,
74+
)
75+
76+
vectors_2d = np.array(all_embeddings, dtype=np.float32) # (N, 768)
77+
blobs = ctype.serialize_numpy_bulk(vectors_2d) # list[bytes]
78+
79+
for key, blob in zip(keys, blobs):
80+
session.execute(insert_stmt, [key, blob])
81+
82+
Each ``bytes`` object in the returned list is accepted directly by the
83+
driver's bytes-passthrough path, so ``BoundStatement.bind()`` performs no
84+
further conversion.
85+
86+
**Supported subtypes** – the fast paths are available for ``float``
87+
(``>f4``), ``double`` (``>f8``), ``int`` (``>i4``), and ``bigint``
88+
(``>i8``). Variable-length subtypes (``smallint``, ``tinyint``, text
89+
types, etc.) fall back to the original element-by-element serialization
90+
automatically.
91+
92+
**Benchmarks** – on 768-dimension ``float32`` vectors (100-row batches),
93+
the bulk path is ~146× faster than the baseline, and the bytes
94+
passthrough path is ~298× faster. See
95+
``benchmarks/bench_vector_numpy_serialize.py`` for reproducible numbers.

0 commit comments

Comments
 (0)