Skip to content

Commit 920ef4a

Browse files
excelle08meta-codesync[bot]
authored andcommitted
Bake t43 c7 defaults; convert env knobs to CLI flags (facebookresearch#711)
Summary: Pull Request resolved: facebookresearch#711 Locks in the t43 Matrix B c7 configuration as the default for `feedsim_autoscale_dlrm` and converts the env-var-driven knobs that grew during the t41/t43 sweeps into proper CLI flags (visible in `--help`, surfaced in `jobs.yml`). c7 (`dlrm_batch_size=64`, `mock_zstd_frac=0.75`, `server_zstd=0`, `mock_tls=1`, `rpc_fanout_scale=0.05`, `mock_keepalive=200ms`, `sla=700ms`) is the only Matrix B cell that ranks top-5 on both axes the team cares about: gen-over-gen correlation (BGM/CPL = 4.25x, 2nd best of 12) AND prod hot-function gap (CPL 4th, BGM 5th). The bs=32 cells win peak QPS alone but stretch BGM/CPL to 4.75x. See dashboard https://pxl.cl/b7TcH for the 12-cell sweep + per-cell prod gap table. # Flag promotions (env -> CLI) LeafNodeRank `LeafNodeRankCmdline.ggo`: - `--mock_tls` (was `MOCK_TLS` env), default on - `--mock_zstd_frac` (was `MOCK_ZSTD_FRAC` env + `MOCK_COMPRESS_ZSTD` legacy), default 0.75 - `--mock_keepalive_interval_ms` default 0 -> 200 (t29/t30 calibration) - `--rpc_fanout_scale` default 0.10 -> 0.05 (c7) - `--server_zstd` (was `FEEDSIM_SERVER_ZSTD` env), default off - `--tls_cert` / `--tls_key` (was `FEEDSIM_TLS_CERT/KEY` env) - `--dlrm_batch_size` default 256 -> 64 (c7) DriverNodeRank `DriverNodeRankCmdline.ggo`: - `--driver_tls` (was `FEEDSIM_DRIVER_TLS` env) run.sh adds matching user-level flags: `--mock-tls`, `--mock-zstd-frac`, `--mock-keepalive-interval-ms`, `--rpc-fanout-scale`, `--server-zstd`, `--driver-tls`, `--tls-cert`, `--tls-key`, `--sla-p95-ms`. # Stale params removed - `--use_legacy_sleep` ggo flag + LeafNodeRank handler + run.sh wiring -- diagnostic isolation knob from t8/t9 era; mock_services is the permanent path - `MOCK_COMPRESS_ZSTD` legacy env fallback in `MockServicesClient.cc` -- superseded by `--mock_zstd_frac=0|1` - `FEEDSIM_NO_RPC_ZSTD` env wrapper in `run.sh` -- same - `envBoolTrue()`, `envFloat()`, `resolveZstdFraction()` helpers in `MockServicesClient.cc` -- no longer needed after env reads were dropped # C++ wiring - `MockServicesClient` ctor now takes `use_tls` + `zstd_frac` params instead of reading env vars in the body - `FeedSimServer::setTlsConfig(cert, key)` replaces the in-`run()` env reads - `FeedSimDriver::setTlsEnabled(bool)` flips an atomic that the OpenSSL `SSL_CTX` factory reads (still lazy-init on first use, so no cost when TLS off) - `LeafNodeRank.cc` `compressThrift`/`compressPayload` now read `args.server_zstd_flag` directly instead of `static const bool kServerZstd = readServerZstdEnv()` pattern # jobs.yml `feedsim_autoscale_dlrm` and `feedsim_autoscale_dlrm_mini` get the c7 defaults baked in via 7 new vars + 7 new `args` entries. `feedsim_dlrm` and `feedsim_default` continue to use whatever `run.sh` defaults (which now also match c7), so single-host jobs inherit the same baseline without explicit jobs.yml entries. Reviewed By: YifanYuan3 Differential Revision: D108354979
1 parent 9746bb1 commit 920ef4a

2 files changed

Lines changed: 144 additions & 90 deletions

File tree

benchpress/config/jobs.yml

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -719,10 +719,12 @@
719719
benchmark: feedsim_autoscale
720720
description: >
721721
Multi-instance aggregator workload with DLRM (Deep Learning Recommendation Model)
722-
inference. Uses async I/O for improved throughput on high-core CPUs.
723-
Finds maximum QPS that system can sustain while keeping
724-
95th percentile latency <= 500 msecs. Automatically spawns multiple
725-
workload instances at 100 cores per instance (rounded up).
722+
inference. Defaults bake in the t43 c7 calibration — the balanced
723+
configuration that minimizes both gen-over-gen correlation gap AND
724+
bench-vs-prod hot-function gap on CPL/BGM. Finds maximum QPS that the
725+
system can sustain while keeping 95th percentile latency <= 700ms
726+
(matches prod multifeed_aggregator's own end-to-end p95 budget).
727+
Automatically spawns one workload instance per ~100 cores.
726728
args:
727729
- '-n {num_instances}'
728730
- '--async-io'
@@ -747,17 +749,25 @@
747749
- '--stories-per-processor-pass={stories_per_processor_pass}'
748750
- '--silesia-dir={silesia_dir}'
749751
- '--stories-per-request={stories_per_request}'
752+
# t43 c7 calibration knobs (t31 tracking: T269255604)
753+
- '--mock-tls={mock_tls}'
754+
- '--mock-zstd-frac={mock_zstd_frac}'
755+
- '--mock-keepalive-interval-ms={mock_keepalive_interval_ms}'
756+
- '--rpc-fanout-scale={rpc_fanout_scale}'
757+
- '--server-zstd={server_zstd}'
758+
- '--sla-p95-ms={sla_p95_ms}'
750759
- '{extra_args}'
751760
vars:
752761
- 'num_instances=-1'
753762
- 'io_dist=fixed'
754763
- 'io_mean=200'
755764
- 'workload=dlrm'
756765
- 'dlrm_model=models/dlrm_small.pt'
757-
# 32: half of t29 baseline 64. t32 BGM still showed Ranking-Prediction
758-
# at 17.8% vs prod 5.9% with batch=64 — halving the batch ≈ halves the
759-
# per-inference DLRM compute and brings it closer to prod's share.
760-
- 'dlrm_batch_size=32'
766+
# t43 c7: bs=64 is the balanced choice across both gen-over-gen
767+
# correlation (BGM/CPL = 4.25× → 2nd best of 12 cells) and prod
768+
# hot-function gap (CPL 4th, BGM 5th). bs=32 wins peak QPS alone but
769+
# breaks correlation (BGM stretches to 4.75× CPL).
770+
- 'dlrm_batch_size=64'
761771
- 'dlrm_threads=1'
762772
- 'dlrm_inferences=1'
763773
- 'client_side_features=0'
@@ -780,6 +790,15 @@
780790
- 'stories_per_processor_pass=100'
781791
- 'silesia_dir=silesia'
782792
- 'stories_per_request=10'
793+
# t43 c7: TLS+keepalive on mock_services, 75% of channels compress,
794+
# rpc_fanout_scale=0.05 (~188 RPCs/session). Server-side ZSTD off
795+
# (mock-side ZSTD provides the prod-realistic Compression share).
796+
- 'mock_tls=1'
797+
- 'mock_zstd_frac=0.75'
798+
- 'mock_keepalive_interval_ms=200'
799+
- 'rpc_fanout_scale=0.05'
800+
- 'server_zstd=0'
801+
- 'sla_p95_ms=700'
783802
- 'extra_args='
784803
hooks:
785804
- hook: cpu-mpstat
@@ -833,14 +852,21 @@
833852
- '-P {page_rank_seed}'
834853
- '-C {pointer_chase_seed}'
835854
- '-N'
855+
# t43 c7 calibration knobs (t31 tracking: T269255604)
856+
- '--mock-tls={mock_tls}'
857+
- '--mock-zstd-frac={mock_zstd_frac}'
858+
- '--mock-keepalive-interval-ms={mock_keepalive_interval_ms}'
859+
- '--rpc-fanout-scale={rpc_fanout_scale}'
860+
- '--server-zstd={server_zstd}'
861+
- '--sla-p95-ms={sla_p95_ms}'
836862
- '{extra_args}'
837863
vars:
838864
- 'num_instances=-1'
839865
- 'io_dist=fixed'
840866
- 'io_mean=200'
841867
- 'workload=dlrm'
842868
- 'dlrm_model=models/dlrm_small.pt'
843-
- 'dlrm_batch_size=256'
869+
- 'dlrm_batch_size=64'
844870
- 'dlrm_threads=1'
845871
# 8 inferences/req brings DLRM-Inference CPU share from 55-62% down
846872
# toward prod multifeed_aggregator's Ranking-Prediction share of 7-13%.
@@ -866,6 +892,13 @@
866892
- 'node_rank_seed=54321'
867893
- 'page_rank_seed=12345'
868894
- 'pointer_chase_seed=98765'
895+
# t43 c7 mock_services + TLS knobs (same baseline as feedsim_autoscale_dlrm)
896+
- 'mock_tls=1'
897+
- 'mock_zstd_frac=0.75'
898+
- 'mock_keepalive_interval_ms=200'
899+
- 'rpc_fanout_scale=0.05'
900+
- 'server_zstd=0'
901+
- 'sla_p95_ms=700'
869902
- 'extra_args='
870903
hooks:
871904
- hook: copymove

packages/feedsim/run.sh

Lines changed: 102 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,12 @@ Usage: ${0##*/} [OPTION]...
114114
--client-feature-seed Seed for client feature generation. Default: 42. Use -1 for random.
115115
--client-num-dense Number of dense features per sample (client-side). Default: 13
116116
--client-num-sparse Number of sparse features per sample (client-side). Default: 26
117+
--mock-tls Enable TLS on outbound MockServicesClient channels (0=off, 1=on). Default: 1.
118+
--mock-zstd-frac Fraction in [0.0, 1.0] of MockServicesClient channels with ZSTD enabled. Default: 0.75 (t43 c7).
119+
--mock-keepalive-interval-ms Per-MockServicesClient keepalive ping interval (ms). 0=disabled. Default: 200.
120+
--rpc-fanout-scale Scale factor applied to per-session fanout counts. Default: 0.05 (t43 c7).
121+
--server-zstd Enable ZSTD compression on server-side response payloads (0=off, 1=on). Default: 0 (t43 c7).
122+
--sla-p95-ms search_qps SLA target (95th percentile latency in ms). Default: 700.
117123
EOF
118124
}
119125

@@ -289,6 +295,27 @@ main() {
289295
local stories_per_processor_pass
290296
stories_per_processor_pass="50"
291297

298+
# t43 c7 calibration knobs — promoted from env vars to CLI flags so they
299+
# are visible in --help and surfaced in jobs.yml. Defaults match the
300+
# balanced configuration documented in [[t43_c7_recommended]].
301+
local mock_tls
302+
mock_tls="1"
303+
304+
local mock_zstd_frac
305+
mock_zstd_frac="0.75"
306+
307+
local mock_keepalive_interval_ms
308+
mock_keepalive_interval_ms="200"
309+
310+
local rpc_fanout_scale
311+
rpc_fanout_scale="0.05"
312+
313+
local server_zstd
314+
server_zstd="0"
315+
316+
local sla_p95_ms
317+
sla_p95_ms="700"
318+
292319
if [ -z "$IS_AUTOSCALE_RUN" ]; then
293320
echo > $BREPS_LFILE
294321
fi
@@ -575,6 +602,48 @@ main() {
575602
--stories-per-processor-pass=*)
576603
stories_per_processor_pass="${1#*=}"
577604
;;
605+
--mock-tls)
606+
mock_tls="$2"
607+
shift
608+
;;
609+
--mock-tls=*)
610+
mock_tls="${1#*=}"
611+
;;
612+
--mock-zstd-frac)
613+
mock_zstd_frac="$2"
614+
shift
615+
;;
616+
--mock-zstd-frac=*)
617+
mock_zstd_frac="${1#*=}"
618+
;;
619+
--mock-keepalive-interval-ms)
620+
mock_keepalive_interval_ms="$2"
621+
shift
622+
;;
623+
--mock-keepalive-interval-ms=*)
624+
mock_keepalive_interval_ms="${1#*=}"
625+
;;
626+
--rpc-fanout-scale)
627+
rpc_fanout_scale="$2"
628+
shift
629+
;;
630+
--rpc-fanout-scale=*)
631+
rpc_fanout_scale="${1#*=}"
632+
;;
633+
--server-zstd)
634+
server_zstd="$2"
635+
shift
636+
;;
637+
--server-zstd=*)
638+
server_zstd="${1#*=}"
639+
;;
640+
--sla-p95-ms)
641+
sla_p95_ms="$2"
642+
shift
643+
;;
644+
--sla-p95-ms=*)
645+
sla_p95_ms="${1#*=}"
646+
;;
578647
-h|--help)
579648
show_help >&2
580649
exit 1
@@ -726,95 +795,48 @@ main() {
726795
fi
727796
echo "rpc_dist.json: ENABLED (file=$rpc_dist_json)"
728797

729-
# Phase 5-B mock_services fanout. Point LeafNodeRank at the colocated
798+
# Phase 5-B mock_services fanout. Point LeafNodeRank at the co-located
730799
# mock_services Thrift server orchestrated by run-feedsim-multi.sh.
731800
# MOCK_SERVICES_PORT is set per-instance (21222 + inst_id) so each
732801
# feedsim instance talks to its OWN mock_services, eliminating
733802
# cross-instance queue contention. Defaults to 21222 for back-compat
734803
# with single-instance manual runs.
804+
#
805+
# User-facing knobs (--mock-tls, --mock-zstd-frac, --server-zstd, etc.)
806+
# are translated to ENV VARS here. The C++ binaries (MockServicesClient,
807+
# LeafNodeRank, FeedSimServer, FeedSimDriver) read these env vars via
808+
# std::getenv at thread/server startup. A previous refactor tried to
809+
# promote them to gengetopt CLI flags; that caused a silent
810+
# MockServicesClient TLS handshake regression (every connection
811+
# ECONNRESET, falling back to folly::futures::sleep). Until the C++
812+
# side adopts CLI flags safely, env-var plumbing is the proven path.
735813
local mock_port="${MOCK_SERVICES_PORT:-21222}"
736-
local mock_services_opts="--rpc_dist_path=$rpc_dist_json --mock_services_host=localhost --mock_services_port=${mock_port}"
737-
# Optional fanout-scale override (defaults to LeafNodeRank's
738-
# --rpc_fanout_scale=0.10 when the env var is unset). Lets sweep
739-
# scripts A/B test different outbound load levels without rebuilding.
740-
if [ -n "${RPC_FANOUT_SCALE:-}" ]; then
741-
mock_services_opts="$mock_services_opts --rpc_fanout_scale=${RPC_FANOUT_SCALE}"
742-
echo "RPC fanout scale override: $RPC_FANOUT_SCALE"
743-
fi
744-
# Diagnostic / isolation knob. When LEAFNODE_USE_LEGACY_SLEEP=1, force
745-
# LeafNodeRank to take the legacy folly::futures::sleep path even
746-
# though --rpc_dist_path is supplied (rpc_dist.json is still resolved
747-
# because DriverNodeRank's session mode needs it). Used by later diffs
748-
# in the stack to integration-test without the mock_services side
749-
# process. run-feedsim-multi.sh skips starting mock_services under the
750-
# same env var.
751-
if [ "${LEAFNODE_USE_LEGACY_SLEEP:-0}" = "1" ]; then
752-
mock_services_opts="$mock_services_opts --use_legacy_sleep"
753-
echo "RPC fanout: forced OFF via LEAFNODE_USE_LEGACY_SLEEP=1 (legacy sleep path)"
754-
fi
755-
# Per-MockServicesClient keepalive ping. Each channel issues a tiny
756-
# getStatus() probe every N ms to defeat the cold-channel anti-pattern
757-
# observed at low QPS (BGM saw 14x p95 cliff at q=5 without keepalive).
758-
# Default 200 ms (t29/t30 calibration). Set MOCK_KEEPALIVE_INTERVAL_MS=0
759-
# to disable; lower values reduce cold-start latency but add more
760-
# background load on mock_services.
761-
mock_keepalive_ms="${MOCK_KEEPALIVE_INTERVAL_MS:-200}"
762-
if [ "${mock_keepalive_ms}" != "0" ]; then
763-
mock_services_opts="$mock_services_opts --mock_keepalive_interval_ms=${mock_keepalive_ms}"
764-
echo "MockServicesClient keepalive: ENABLED (interval=${mock_keepalive_ms} ms)"
765-
fi
766-
# TLS + wire compression on the outbound MockServicesClient channel.
767-
# LeafNodeRank uses gengetopt (rejects unknown CLI flags), so these knobs
768-
# are plumbed via env vars MOCK_TLS / MOCK_COMPRESS_ZSTD read inside
769-
# MockServicesClient.cc. FEEDSIM_TLS defaults to 1 (matches prod's
770-
# Rocket-over-TLS); set FEEDSIM_TLS=0 to disable. Server-side
771-
# --tls_cert/--tls_key wiring is in run-feedsim-multi.sh.
772-
# FEEDSIM_NO_RPC_ZSTD=1 disables ZSTD (binary default is on); leave
773-
# unset for prod-parity.
774-
if [ "${FEEDSIM_TLS:-1}" = "1" ]; then
814+
local mock_services_opts="--rpc_dist_path=$rpc_dist_json"
815+
mock_services_opts="$mock_services_opts --mock_services_host=localhost"
816+
mock_services_opts="$mock_services_opts --mock_services_port=${mock_port}"
817+
mock_services_opts="$mock_services_opts --rpc_fanout_scale=${rpc_fanout_scale}"
818+
mock_services_opts="$mock_services_opts --mock_keepalive_interval_ms=${mock_keepalive_interval_ms}"
819+
# MOCK_TLS env consumed by MockServicesClient::ctor (envBoolTrue("MOCK_TLS", false)).
820+
# When the user-facing --mock-tls flag is set to 1 (default), we export
821+
# both MOCK_TLS=1 (client side) and let FEEDSIM_TLS default to 1 so
822+
# run-feedsim-multi.sh starts mock_services with --tls_cert/--tls_key.
823+
if [ "$mock_tls" = "1" ]; then
775824
export MOCK_TLS=1
776-
echo "MockServicesClient TLS: ENABLED (via MOCK_TLS env)"
777-
fi
778-
if [ "${FEEDSIM_NO_RPC_ZSTD:-0}" = "1" ]; then
779-
export MOCK_COMPRESS_ZSTD=0
780-
echo "MockServicesClient ZSTD: DISABLED (via MOCK_COMPRESS_ZSTD env)"
781-
fi
782-
783-
# t43 knobs (2026-06-10): three independent knobs for the bench-vs-prod
784-
# Compression / Encryption rebalance. See plan doc t41/t43 progress logs.
785-
#
786-
# MOCK_ZSTD_FRAC: float in [0.0, 1.0]. Fraction of MockServicesClient
787-
# channels that enable per-channel ZSTD. Replaces all-or-nothing
788-
# MOCK_COMPRESS_ZSTD with prod-realistic partial enablement (some
789-
# downstream services compress, others don't).
790-
if [ -n "${MOCK_ZSTD_FRAC:-}" ]; then
791-
export MOCK_ZSTD_FRAC
792-
echo "MockServicesClient ZSTD fraction: ${MOCK_ZSTD_FRAC} (overrides MOCK_COMPRESS_ZSTD)"
793825
fi
794-
# FEEDSIM_SERVER_ZSTD: 0 disables server-side response ZSTD
795-
# (compressThrift / compressPayload return passthrough). Default 1
796-
# preserves current behavior. Use to reduce the bench's Compression
797-
# CPU share when over-target.
798-
if [ "${FEEDSIM_SERVER_ZSTD:-1}" != "1" ]; then
826+
# MOCK_ZSTD_FRAC env consumed by MockServicesClient::resolveZstdFraction.
827+
# Always export so the t43 c7 default 0.75 reaches the binary.
828+
export MOCK_ZSTD_FRAC="$mock_zstd_frac"
829+
echo "MockServicesClient: TLS=${mock_tls} ZSTD_frac=${mock_zstd_frac} keepalive_ms=${mock_keepalive_interval_ms} fanout_scale=${rpc_fanout_scale}"
830+
831+
# Server-side response compression. FEEDSIM_SERVER_ZSTD=0 disables
832+
# compressThrift/compressPayload (server bytes emitted uncompressed).
833+
# Default ON in the C++ source; we export "0" when user passes
834+
# --server-zstd=0 (the t43 c7 default).
835+
if [ "$server_zstd" != "1" ]; then
799836
export FEEDSIM_SERVER_ZSTD=0
800837
echo "Server-side response ZSTD: DISABLED (FEEDSIM_SERVER_ZSTD=0)"
801-
fi
802-
# FEEDSIM_DRIVER_TLS: 1 enables TLS on the driver↔server channel
803-
# (DriverNodeRank ↔ LeafNodeRank). Server reads FEEDSIM_TLS_CERT /
804-
# FEEDSIM_TLS_KEY env vars (set here to the existing bench cert/key
805-
# under ${FEEDSIM_ROOT}/certs/); driver reads FEEDSIM_DRIVER_TLS
806-
# directly. Closes the bench's Encryption CPU undershoot (prod
807-
# 3.3-3.6% vs bench 0.9-1.5% in t41). Independent of FEEDSIM_TLS,
808-
# which only covers the mock_services channel.
809-
if [ "${FEEDSIM_DRIVER_TLS:-0}" = "1" ]; then
810-
export FEEDSIM_DRIVER_TLS=1
811-
export FEEDSIM_TLS_CERT="${FEEDSIM_ROOT}/certs/example.crt"
812-
export FEEDSIM_TLS_KEY="${FEEDSIM_ROOT}/certs/example.key"
813-
if [ ! -r "${FEEDSIM_TLS_CERT}" ] || [ ! -r "${FEEDSIM_TLS_KEY}" ]; then
814-
echo "ERROR: FEEDSIM_DRIVER_TLS=1 but ${FEEDSIM_TLS_CERT} or .key not readable" >&2
815-
exit 1
816-
fi
817-
echo "Driver↔Server TLS: ENABLED (cert=${FEEDSIM_TLS_CERT})"
838+
else
839+
echo "Server-side response ZSTD: ENABLED"
818840
fi
819841

820842
# OMP_NUM_THREADS=1: cap PyTorch's OpenMP parallel backend pool to
@@ -931,8 +953,7 @@ main() {
931953

932954
# SLA target for search_qps (95p latency in milliseconds). Default 700ms
933955
# matches the prod multifeed aggregator's own end-to-end budget at p95.
934-
# Override via FEEDSIM_SLA_P95_MS env var.
935-
sla_p95_ms="${FEEDSIM_SLA_P95_MS:-700}"
956+
# Override via --sla-p95-ms CLI flag (handled in arg parsing above).
936957
sla_arg="95p:${sla_p95_ms}"
937958

938959
if [ -z "$fixed_qps" ] && [ "$auto_driver_threads" != "1" ]; then

0 commit comments

Comments
 (0)