Meetup

Dataframes Are All You Need: MLOps on Easy Mode

Jay Chia, EventualEpisode 124 · 57:25 · Jun 2023 · 581 viewsHosted by Demetrios Brinkmann
Thumbnail for Dataframes Are All You Need: MLOps on Easy Mode Watch on YouTube
TL;DR
  1. 1

    A data frame can cover much of the MLOps workflow, from loading and exploring data through processing, training input, batch inference, and evaluation.

  2. 2

    Daft extends the data frame abstraction to complex data such as images, PDFs, audio, point clouds, and Python objects while supporting distributed execution.

  3. 3

    Daft's lazy execution lets it optimize chained operations, prune unused columns, fuse work into pipelines, and run the same code locally or on a Ray cluster.

Summary

Jay Chia argues that teams can start an MLOps stack with a good data frame library on top of storage, rather than assembling many separate systems immediately. He divides MLOps into data systems, training, and productionization, then shows how data frames fit each part. Daft is his running example. It can read and write data, join and aggregate tables, process complex values such as images, call Python functions, feed batches into PyTorch training, and run models over large datasets. The demo starts with COCO annotations in Parquet, downloads image URLs, converts bytes into images, crops objects using bounding boxes, and produces NumPy arrays. Daft is lazy, so these operations can be planned and fused before execution. The same workflow can run on a laptop or across a Ray cluster. Jay also discusses planned streaming support, native image types, more data sources, and integrations.

Key ideas
04:46

A data frame is a programmable table with useful type guarantees

Jay defines a data frame as a table that a program can manipulate. It has rows, named columns, and a data type for each column. Those types let the library guarantee that values in a column have a consistent type and enable operations over the table. He uses Daft to show columns containing unsigned integers, lists of coordinates, and other values. Pandas is one implementation of the idea, but Jay asks the audience to think of the abstraction more broadly. Libraries differ in whether they execute eagerly or lazily, which data types they accept, whether they distribute work, and how fast they run.

07:27

Lazy execution lets a data frame avoid work that the query does not need

Jay contrasts eager data frames, where each command runs immediately, with lazy ones such as Daft. A lazy data frame builds a query plan and waits until an operation such as showing or collecting the data is requested. That gives the engine information it can use to optimize execution. If a query needs only one column, Daft can avoid reading another column from storage. Later, Jay explains that chained operations can be fused into one pipeline. Downloading an image, converting it, cropping it, and turning it into a smaller array can run as one pipeline, which reduces intermediate memory use.

21:00

Data frames can cover the main data work around training and batch inference

Jay divides MLOps into data systems, training, and productionization. In the data portion, a data frame can read and write storage, explore data with statistics and group-bys, clean values, and run heavier processing. For training, it can prepare and ingest data fast enough to keep GPUs busy, then help evaluate predictions across groups such as geography or job occupation. In production, the same abstraction can run a model in batch and join predictions with later outcomes. He presents this as a way to reduce the amount of infrastructure needed when starting an ML system, while acknowledging that more specialized systems may fit particular use cases.

18:24

Complex data should live in the same table abstraction as ordinary columns

Jay says traditional data frames are often built around numbers, strings, and dates, which creates a split when a workflow also contains images, PDFs, JSON, XML, HTML, or point clouds. A common pattern is to keep table metadata in one system, store file URLs in a column, and run a separate batch job over the files. He considers that difficult to manage because the workflow spans two systems. Daft instead allows complex values in data frame columns. In his example, a URL becomes image bytes, then an image, then a cropped image, all within the data frame. Daft supports Python objects and is adding native types for images and other data.

22:36

The Daft demo turns COCO annotations and image URLs into training tensors

Jay's demo uses the COCO image dataset. He reads Parquet files for images, annotations, and categories, joins annotations with category names, and groups by name to inspect class counts. He then joins in image URLs and selects the object ID, URL, bounding box, and category. Daft downloads each URL into an image-bytes column, applies a Python function to create image objects, and applies another function to crop each image using its bounding box. The cropped images are resized to 224 by 224, then converted into NumPy arrays. The resulting columns can be renamed as image and label before being passed into batched PyTorch input.

33:52

The same data-frame code can scale from a laptop to a Ray cluster

Daft runs locally with a lightweight Python multithreading backend, and Jay also demonstrates it on a Ray cluster. After connecting to the cluster, the data frame code stays the same. The computation can run across the available machines instead of only on the laptop. Jay partitions the data so work can run in parallel, then changes the preview-style execution to collect the full dataset. He reports running the image workflow over roughly 40,000 rows in the demonstration. Daft can also receive a resource request for a GPU on a step that runs a model, allowing the scheduler to provision a GPU for that user-defined function.

21:19

A data frame can provide the table layer while storage remains separate

Jay's proposed starting point is storage such as S3 plus a data frame query engine, with Python and the ML ecosystem running on machines downstream. The best choice depends on the data. For purely tabular use cases, he says SQL and systems such as Snowflake may be a good fit. For complex data that needs to connect naturally to Python pipelines, he suggests a system like Daft. He also explains that storing images inside a columnar format can be reasonable when the format supports column pruning and predicate pushdown. For high-throughput training, compacting data into a format such as Parquet or a TFRecord-like layout may be preferable. Low-latency applications may instead need a database and caching.

47:00

Daft's streaming design would treat incoming objects as rows in an unbounded data frame

In the questions, Jay describes streaming as work in development rather than a finished part of the main product. A future source could watch a bucket and turn each new object into a new row. A streaming sink could write transformed results elsewhere. This would let a data frame handle processing between the source and sink, including model execution and preprocessing. He notes that some table operations need different semantics on a stream, such as sorting, while windowed operations can make certain batch-style computations possible. The idea is to keep the data-frame interface while allowing computation to continue as data arrives.

"If you run all these things in sequence, we don't actually fire them off as separate tasks, we fuse them all together and run them on one pipeline."Jay Chia50:06
Who should watch
  • You are building an ML data pipeline that has images, documents, or other values that do not fit comfortably into ordinary SQL-shaped tables.
  • Your training GPUs spend too much time waiting for data, and you want one Python-facing layer for loading, transforming, and batching inputs.
  • You are deciding whether your early MLOps stack needs multiple specialized systems or can begin with storage and a distributed data frame.