Vibeleaderboard
← All Intel
Intel / article

F3 Lightning: How Meta Accelerates Ads ML Features to Production at Scale

Source
engineering.fb.com
Date

Context

Meta has changed how new inputs for its ads-ranking models reach production so that each one ships or is rolled back on its own, while its servers still compute shared work only once. These inputs are features: values a model reads before it predicts, such as how many ads a person clicked in the past seven days. According to Meta's engineering post, a single ads request can need more than 20,000 of them. With the new layer, called F3 Lightning, Meta says comparable extraction features reach production about 3.6 times faster than under its earlier system, with no increase in infrastructure compute cost.

The earlier system, F3, saved computation by merging features, and that merge is what slowed releases. Computing a feature takes steps such as reading stored events, filtering them to a time window and counting the result, and many features share those steps: a seven-day click count and a seven-day impression count can read the same source through the same filter. F3 describes each feature as a small dependency graph in which each node does one step and each link records which step needs another's result. Its compiler joined every feature's graph into one and collapsed identical steps, so shared work ran once per request. The merged graph was also the unit that got released, so one invalid definition stopped every other feature from shipping. Meta says failures grew more frequent as F3 went from a few hundred features to more than 20,000, and features that live models already use need expensive model tests late in the release process, which held back everything merged with them.

F3 Lightning compiles each feature into its own self-contained configuration, which turns releases into a priority queue: a feature no model uses yet can go out on standard checks, while a change to a feature a live model reads gets extra testing first. Meta's first prototypes also ran each configuration separately and used substantially more CPU, because they repeated the shared steps. Four changes brought cost back to parity. The compiler now identifies each computation by what it does (its operation, parameters and inputs), so identical work from features compiled weeks apart receives the same identifier. At startup, the server builds one execution plan across all active features, keeps a single copy of each shared step and flattens the plan into an ordered list that runs in one pass per request; if a step fails, only the work that depends on it is skipped. Each request then gets one shared memory buffer instead of a separate container per feature, so consecutive steps read neighboring memory and a list result used by 20 features is stored once. Finally, every identifier is mapped to a numbered slot, so reading a result becomes a direct array lookup instead of a hash-table search.

The design treats what ships together and what runs together as separate decisions, and Meta's own account shows why removing duplicate work was not enough. Once no step ran twice, CPU use still sat above F3 until the scattered per-feature copies were consolidated into the shared buffer. Meta calls this the least obvious result of the project and the one most likely to apply elsewhere: on modern processors, where results sit in memory and how many copies exist can matter as much as how many computations run. The payoff Meta claims is a shorter release cycle, which lets its ads models be improved and retrained more often in the same period.

Key takeaways · AI-distilled
  • Meta's F3 compiled all ads features into one merged graph so shared steps ran once per request, but that graph was also the release unit. With more than 20,000 features, one invalid definition blocked every release, and slow model tests on one feature held up the rest.
  • F3 Lightning compiles each feature into its own self-contained configuration that is validated, shipped and rolled back alone. A priority queue ships features no live model reads on standard checks, while changes to features a model already uses get extra testing first.
  • To share work without a merged graph, the compiler derives each node's ID from its operation, parameters and input IDs, so identical computations compiled weeks apart match. At startup the runtime keeps one copy of each and flattens every feature into a single ordered plan.
  • Meta says removing duplicate computation was not enough: CPU stayed above the old F3 until per-feature data containers became one shared buffer per request, with a separate readiness vector and integer slot indexes replacing hashed lookups on the request path.
  • Per Meta, comparable features now reach production about 3.6x faster than on F3 with no added infrastructure compute. A failed computation marks only its downstream nodes as not ready, so independent features in the shared plan keep running.
Read the source engineering.fb.com
Recommended reads
Comments

Checking sign-in…

Loading comments…