한 줄 요약X가 For You 랭킹 모델의 학습에 광고 구매액 loss를 연결하고(기본 가중 0), 클릭 후 체류 시간 head를 기본 설정부터 10초 기준 이진 분류로 바꿨다.
오늘 함께 본 다른 변화는 다음과 같다.
X는 같은 커밋에서 성별 피처의 임베딩 인덱스 매핑을 소리 없이 바꿨다.
X의 광고 브랜드 안전 V2 게이트는 미러 값이 true에서 false로 롤백됐다.
Meta 저자들이 Facebook Marketplace 후보 생성 단계의 카테고리 상한을 유저마다 다르게 거는 PCap 논문을 냈다.
1광고 구매액 loss를 학습에 연결하고, 체류 시간 head를 이진 분류로 바꿨다 — X
자료xai-org/x-algorithm@fad2f71 — GitHub 커밋, 2026-09-16 01:11Z, 소스코드. 바뀐 파일은 26개(+552/−233)다. 이 노트들은 4세대 공개 뒤 매일 이어지는 X 커밋에 차례로 번호를 붙여 부르며, 이 커밋은 4세대+22다.
배경 Phoenix(X For You 피드의 랭킹 트랜스포머)는 행동마다 출력 head를 두고, 체류 시간이나 구매액 같은 연속값은 continuous head로 예측한다. 4세대+21(2d4a03c)에서는 광고 구매액 continuous head의 wire만 열렸다. 이 head는 ADS_WEB_CT_PURCHASE_VALUE이고, 요청 필드는 PurchaseValueBaseline이다. 이번 커밋은 세 가지 옵트인 연결(purchase value, binary loss, click_dwell feature)을 함께 넣었고, 그중 이 head를 학습 loss까지 잇는 것이 가장 눈에 띄는 변경이다.
새로 알게 된 것A. 광고 구매액 loss가 학습 그래프에 연결됐지만, 기본 가중은 0이다
첫 사용처는 click_dwell_time이다(threshold=10s, default weight=1.0).
기본 학습 config는 이번 커밋 안에서 click_dwell_time head를 10초 기준 이진 분류로 학습하게 됐다. _home_direct_packed_base의 default가 click_dwell_loss_weight: 1.0과 enable_click_dwell_time: True(feature-prep)로 바뀌었다.
ContinuousActionLossConfig가 새 loss_type="binary"를 받고, binary_threshold: float = 10.0 필드가 추가됐다.
활성화는 sigmoid로 강제된다. output_cap은 출력이 확률 [0,1]이라 assert로 금지된다.
loss는 binary_threshold_loss_compute(gt_raw, logit, valid_mask, negative_sample_mask, threshold=10.0, mask_negatives=True, raw_weights=None)가 계산한다. 이 함수는 gt_binary = (gt_raw > threshold).float()로 정답을 이진화한 뒤 optax sigmoid BCE로 loss를 낸다.
상수 GEMMA_REPLY_SPAM = "oai-gemma4-26b-reply-spam"이 새로 생겼다. 이 모델은 전용 파인튜닝 변종으로 추정된다. GEMMA_REPLY_SPAM_MIN_FOLLOWERS = 150_000은 모델 라우팅에, GROK_GEMMA_FOLLOWER_SPLIT = 180_000은 task 자격에 쓴다.
판정 모델은 SimpleReplyScorer._sampler(post)가 고른다. max(post.ancestors[0].user.follower_count, post.ancestors[-1].user.follower_count) > 150_000이면 oai_gemma4_reply_spam을, 그 이하면 기본 oai_gemma4를 쓴다.
task filter 두 곳의 팔로워 임계가 150000 → GROK_GEMMA_FOLLOWER_SPLIT(180000)로 바뀌었다. 4세대+17(49815da)의 150k에서 180k로 다시 올린 것이다.
바뀐 상수는 TaskSpamFilter.FOLLOWER_COUNT_THRESHOLD_FOR_SPAM_DETECTION과 TaskReplyRankingFilter.FOLLOWER_COUNT_THRESHOLD_FOR_REPLY_RANKING이다.
VF(visibility-filtering, 포스트마다 이 뷰어에게 보여도 되는지 판정하는 서비스) 서브레포에서는 13개 enum이 손으로 짠 as_str() 구현에서 strum::IntoStaticStr 매크로로 통일됐다. 5개 파일에 걸친 변경이다.
대상 enum은 RequestOutcome·SourceOutcome·CacheTier·CacheResult·ManhattanResult·BatchStage·ConnEvent·HydratorOutcome·SafetyLevel·LabelSource·FallbackReason·FailureKind·WarmKeyResult다.
관측 라벨 문자열은 snake_case 그대로 유지되므로 순수 리팩터이고, -180줄이다.
— phoenix/xrex/configs/xrecsys.py, 2026-09-16. _home_direct_packed_base() mparams에는 "click_dwell_loss_weight": 1.0이 동시에 세팅됐다.
def _rescale_sigmoid_heads_for_inference(
candidate_continuous_predictions, continuous_action_losses, product_surface,
):
for loss_config in continuous_action_losses:
if loss_config.activation != "sigmoid" or loss_config.loss_type == "binary":
continue
...
배경 후보 생성(retrieval) 단계에서 다양성을 확보하는 방식은 지금까지 저장소 코퍼스에서 크게 두 축이었다. 하나는 랭킹·재순위에서 MMR·DPP처럼 후보끼리 비슷할수록 벌점을 주는 pairwise similarity penalty로 상위 후보를 재배열하는 축이고, X의 VMRanker DPP와 유튜브의 rerank stage가 여기에 속한다. 다른 하나는 후보 생성기 개수 자체를 늘려 소스 다양성으로 커버리지를 확보하는 축이고, Netflix multi-source retrieval이 그 예다.
논문이 겨냥하는 문제는 waterfall 그리드형 marketplace 지면의 특성이다. multi-source retrieval에서는 source마다 자기 objective에 따른 카테고리 편향이 있어서(예: 어떤 source는 electronics를 과대표한다), 상위 후보 pool의 카테고리 분포가 치우친다. 결국 유저가 참여하는 카테고리도 좁아진다. 또 유저마다 다양성을 원하는 정도가 다른데 모든 유저에게 같은 다양성 정책을 적용하면, "좁게 클릭하는 유저"에게는 과도한 다양성이, "넓게 클릭하는 유저"에게는 부족한 다양성이 걸릴 수 있다. 이번 논문(PCap)은 기존 두 축 사이에 새 축을 넣는다. retrieval scanning 단계에서 카테고리별 상한(cap)을 걸되, 상한 자체를 유저별로 개인화하는 접근이다.
새로 알게 된 것A. PCap은 클릭 카테고리의 엔트로피로 유저를 다양성 버킷에 나누고, 버킷마다 다른 카테고리 상한을 건다
"We propose a personalized capping framework (PCap) to improve the diversity in Facebook Marketplace by introducing user-level diversity constraints at the retrieval stage. PCap models individual diversity preferences using Shannon entropy-based scoring, segments users into diversity buckets, and applies personalized category caps during multi-source candidate retrieval."
— PCap: Personalized Retrieval-Stage Diversity Capping in Facebook Marketplace, 2026-09-15.
정본 반영radar.md의 ## 이번 달 신규 절 맨 위에 PCap 엔트리를 추가했다. Facebook Marketplace는 저장소의 정본 서비스가 아니어서 레이더에서 다룬다. 현재 정본은 x·facebook·instagram·threads·netflix이고, Marketplace는 없다. 다음 관측이 붙으면 topics/feed-diversity.md로 승격할 후보다.
의미 PCap은 저장소가 이미 추적하는 topics/feed-diversity.md에 새 각도를 더한다. 기존 다양성 논의는 MMR·DPP 같은 pairwise 접근(랭킹·재순위)과 multi-source retrieval 대응이 주였다. PCap은 retrieval scanning에 카테고리 상한을 걸되 상한 자체를 유저별로 다르게 세팅하는 방식이고, 두 축 사이에 있는 새 각도다.
첫째, 지연 증가가 작다. Phase 2의 latency +0.8 ms는 랭킹·재순위 단계의 다양성 처리와 대비된다.
광고 구매액 loss의 가중을 실제로 0 이상으로 설정한 config가 언제 나오는지 본다 — 이 값이 활성화되면 광고 랭킹의 loss 조합에서 value-optimizing 축이 실제로 학습에 영향을 미치기 시작한다. 가중은 mparams의 purchase_value_loss_weight다. Baseline offset regression과 raw dollar regression의 실측 학습 곡선이 어떻게 갈리는지가 관측 대상이다.
ContClickDwellTimeWeight 미러가 언제 조정되는지 본다 — click_dwell_loss_weight=1.0과 binary head 활성화로 서빙 예측값 스케일이 60배 축소된 상황이다. 미러상 그대로라면 이 head의 기여가 사실상 축소된 채로 배포되고 있다는 뜻이다.
proto Gender enum의 실제 값 정의를 확인한다 — user_gender의 Male/Female 임베딩 인덱스가 swap됐는지 가려야 한다. enum 정의는 phoenix/crates/serving/xai-recsys-proto/proto/recsys.proto나 xai-proto/proto/recsys.proto에서 확인한다.
EnableAdsBrandSafetyVerdictV2 롤백의 사유가 후속 커밋에서 드러나는지 본다 — EnableAdsBrandSafetyVerdictV2는 4세대+2에서 신설된 뒤 4세대+7까지 확장되는 방향이었다가 이번에 롤백됐다. 사유가 드러나는지 로그·주석·PR 코멘트를 관측한다.
PTS(Parameter Tuning Sequence)를 다른 회사가 채택했다는 진술이 나오는지 본다 — Meta의 다른 지면으로 확장됐다는 진술이나, 두 번째 회사의 비슷한 sequential online tuning 진술이 나오는지 관측한다.