- 읽은 자료 1건
- 정본 반영 1개 파일
- 레이더 0건
1슬레이트 다양성 관측과 광고 구매 금액 예측 헤드가 추가됐다 — X
자료 xai-org/x-algorithm@2d4a03c — xAI 공개 저장소, 2026-09-15 커밋, 코드. 이 노트들은 4세대 공개 뒤의 X 커밋에 차례로 번호를 붙여 부르며, 2d4a03c는 4세대+21이다. 변경은 파일 17개, +592/−9, 5개 축에 걸쳐 있고, diff는 2026-09-16에 GitHub API로 확인했다.
배경 X For You의 최종 슬레이트(한 번에 보여 주는 아이템 묶음)는 랭킹 모델 Phoenix가 매긴 점수를 그대로 따르지 않는다. VMRanker의 DPP(θ=0.65, K=150) 재정렬이 코사인 유사도로 다양성을 강제하고, 작성자 반복 감쇠, OON(out-of-network, 팔로우하지 않은 계정) 배수, 새 작성자 부스트 같은 휴리스틱이 더해진 뒤 남은 것이 슬레이트다. 이 휴리스틱 층이 랭커 원점수에 비해 슬레이트 구성을 얼마나 바꾸는지, 즉 "다양성 개선 vs 랭킹 손실"의 실제 폭을 재는 지표는 지금까지 X 공개 코드에 없었다. 이번 커밋은 그 관측 층을 붙이면서 아래 네 가지도 함께 바꿨다.
- 광고 Phoenix ranker에 구매액 자체를 continuous head로 회귀 예측하는 연결이 새로 열렸다(기존은 클릭·컨버전 확률 헤드만).
- continuous head는 연속값을 회귀로 예측하는 출력 헤드다.
- H100 two-tower 학습 config의 attention 커널이 GB300과 같은 CUTe DSL 계열로 옮겨졌다.
- Kafka OTel export 간격이 30→120초로 완화됐다.
- coordinated spam 필터의 root 팔로워 임계가 10k→30k로 올랐다.
새로 알게 된 것A. 응답의 다양성을 3단계로 나눠 기록하는 관측이 새로 생겼다
home-mixer(For You 피드를 조립하는 서비스)에 응답 다양성을 3단계로 재는 관측 side effect가 새로 생겼다 확인 —
home-mixer/side_effects/response_diversity_stats_side_effect.rs(186줄 신규)- side effect는 응답을 바꾸지 않고 덧붙여 실행되는 파이프라인 단계다.
- 기본으로는 요청의 5%에서만 실행하고, 실험 버킷 안에서는 100% 실행한다. stage마다 12~15개 지표를 histogram으로 내보낸다.
- 함께 바뀐 파일은
home-mixer/candidate_pipeline/phoenix_candidate_pipeline.rs(+2)와home-mixer/params/param.rs(+7)이다.
이 side effect는 Phoenix 후보 파이프라인에 6번째 관측 side effect로 연결됐다 확인(같은 커밋).
- 이름은
ResponseDiversityStatsSideEffect이고, 자리는ScoredStatsSideEffect다음,AuthorServedMetricsSideEffect앞이다.
- 이름은
실행 조건은 두 가지다 확인(같은 커밋).
- 기본: feature-switch param
EnableResponseDiversityStatsExperimentBucket에 실험 버킷이 하나도 잡히지 않으면DEFAULT_SAMPLING_RATE = 0.05, 즉 요청의 5%에서만 실행한다. - 실험: 이 param에 실험 버킷이 잡히면 그 버킷 안에서는 100% 실행하고, 각 지표에
ddg(실험 id)와bucket스코프 태그를 붙여 발행한다. 실험군별 다양성 분포를 따로 관측할 수 있다는 뜻이다.
if experiment_buckets.is_empty() && random::<f64>() >= DEFAULT_SAMPLING_RATE { return Ok(()); }- 기본: feature-switch param
세 stage를 각각 잰다 확인(같은 커밋).
final: 최종 선택된 후보(input.selected_candidates)를score내림차순으로 정렬한 것이다. 사용자에게 실제로 나가는 슬레이트다.top10:final의 상위 10개다(TOP_POSITIONS = 10).pre_heuristic:selected_candidates와non_selected_candidates를 합쳐weighted_score내림차순으로 상위 K개를 뽑는다(K = 최종 슬레이트 크기).weighted_score는 헤드별 확률에 가중치를 곱해 더한 원점수(head-weight sum)로, DPP·author-decay·OON 배수를 적용하기 전 값이다.- 즉
pre_heuristic은 "만약 heuristic 층 없이 원점수 top-K만 그대로 냈다면 어떤 다양성을 갖는 슬레이트였을까"의 counterfactual이다.
stage마다 아래 지표를 발행하며, 이름에는 모두
ResponseDiversity.*접두가 붙는다 확인(같은 커밋).
| 지표 | 축 |
|---|---|
Size |
후보 수 |
UniqueAuthors·UniqueAuthorRatio·MaxAuthorShare |
작성자 축 카디널리티와 집중도 |
AuthorHhi·AuthorEntropyNorm |
HHI(Herfindahl-Hirschman Index: 작성자별 점유율의 제곱합으로, 시장 집중도 지표를 슬레이트에 적용한 것)와 entropy / ln(size)로 정규화한 shannon entropy |
UniqueSources·SourceEntropyNorm |
served_type(Thunder / Phoenix retrieval / SimClusters 등 retrieval 소스 축) 다양성 |
InNetworkShare |
인네트워크(팔로우한 작성자) 후보 비율 |
SidCoverage |
semantic ID(SID, 포스트를 RQ-VAE 계층 코드로 나타낸 ID)가 있는 후보의 비율 |
UniqueSidL1·MaxSidL1Share·SidL1EntropyNorm |
Semantic ID L1(RQ-VAE stacked residual codebook의 최상위 레벨 코드) 다양성 |
UniqueSidL2·SidL2EntropyNorm |
Semantic ID L2 다양성 |
- 어떤 축이든 다중집합 통계를 뽑는 새 primitive
Composition이 생겼다 확인(같은 커밋). 이 구조체는 아래 C의 hydrator가 새 슬레이트 bit를 계산할 때도 다시 쓴다.- 필드는
size,unique,max_count,hhi,entropy_norm이고, 파일은home-mixer/util/composition.rs(63줄 신규)다. from_keys<K: Hash + Eq>(iter)하나로 축에 상관없이 통계를 낸다.
- 필드는
- 표본 확률 5%와 stage 3개의 조합은 랭킹 지연에는 거의 영향을 주지 않으면서 관측 정확도는 유지하는 튜닝이다.
- 정렬은 두 번이고, entropy와 HHI 계산은 벡터를 도는 O(n)이다.
- 실험 버킷일 때만 100% 관측해, tail 분포까지 검증할 수 있게 열어 뒀다.
새로 알게 된 것B. 뷰어가 적극적으로 참여한 작성자를 이력에서 뽑는 파서가 생겼다
요청에 실려 오는 뷰어의 최근 상호작용 이력에서, 긍정적으로 참여한 작성자 id를 모으는 함수가 새로 생겼다 확인 —
home-mixer/util/viewer_history.rs(61줄 신규)- 함수는
positively_engaged_author_ids(columnar_sequence: &bytes::Bytes) -> Option<HashSet<u64>>다. - 입력은 요청에 실린 Arrow IPC 스트림
ScoredPostsQuery.columnar_scoring_sequence다. 유저의 최근 상호작용 이력을 columnar batch로 담아 둔 것이다. authorId가 0보다 크고,actionNameMultiHotfixed-size list에서 18개 positive action 가운데 하나 이상이 켜진 행의 authorId를 모아 돌려준다.
- 함수는
positive action 18개는 다음 목록으로 명시돼 있다 확인(같은 파일).
ServerTweetFav, ServerTweetReply, ServerTweetQuote, ServerTweetRetweet, ClientTweetClick, ClientQuotedTweetClick, ClientTweetOpenLink, ClientTweetClickProfile, ClientTweetPhotoExpand, ClientQuotedTweetPhotoExpand, ClientTweetVideoOpen, ClientTweetVideoQualityView, ClientQuotedTweetVideoQualityView, ClientTweetShare, ClientTweetClickSendViaDirectMessage, ClientTweetShareViaCopyLink, ClientTweetBookmark, ClientTweetFollowAuthor- 즉 리포트·뮤트·블록·
not_dwelled같은 부정 신호와 dwell 같은 노출성 신호는 의도적으로 제외됐다. 영상 quality view 두 개는 목록에 들어 있다.
- 즉 리포트·뮤트·블록·
이 세트는 X 공개 코드의 다른 어느 곳에도 나온 적이 없는 새 상수 집합이다. "적극적 참여로 관계가 형성된 작성자"의 정의를 처음으로 코드에 고정한다.
이 세트가 어떤 랭킹 head에 대응하는지, 즉
phoenix/runners.py:233-253의 positive engagement head 정의와 정확히 일치하는지는 이번 커밋 범위 밖이다.이 함수는 아래 C의 슬레이트 bit 하나(
AUTHOR_NOT_ENGAGED_BY_VIEWER)를 계산하는 데 쓰인다.
새로 알게 된 것C. 후보별 bitset에 슬레이트 다양성을 나타내는 bit 12개가 생겼다
- 후보마다 속성을 bit로 기록하는 bitset에 슬레이트 축 bit 12개가 새로 생겼다 확인 —
home-mixer/candidate_hydrators/tweet_type_metrics_hydrator.rs(+100/−4)- 대상은
TweetTypeMetricsbitset이고, predicate slot은 239-244와 315-320이다. - 함께 바뀐 파일은
home-mixer/util/tweet_type_metrics.rs(+27)와home-mixer/models/candidate.rs(+8)이다.
- 대상은
- 지금까지
TweetTypeMetricsHydrator는 후보 하나하나에 대해 트윗 자체의 속성을 bitset으로 세팅했다.- 예를 들면 리트윗 여부, media 종류, tweet age 버킷, 작성자 팔로워 규모 6단 같은 속성이다.
- 이번 커밋은 여기에 슬레이트 전역 통계를 슬레이트 안 모든 후보에 반영하는 6개 bit(239-244)를 더했다 확인(같은 커밋). 이 bit들은 모든 후보에 똑같이 세팅된다.
UNIQUE_AUTHOR_RATIO_LTE_50_PCT = 239: 슬레이트의 unique_ratio ≤ 0.5UNIQUE_AUTHOR_LTE_5/10/15 = 240/241/242SINGLE_AUTHOR_GTE_25_PCT/50_PCT = 243/244
- 각 후보가 슬레이트 안에서 갖는 문맥을 반영하는 6개 bit(315-320)도 더했다 확인(같은 커밋). 이 bit들은 후보마다 다르게 세팅된다.
AUTHOR_REPEAT_IN_SLATE = 315,AUTHOR_REPEAT_GTE_3_IN_SLATE = 316: score 내림차순으로 순회하면서 같은 author_id를 두 번째, 세 번째 이상 만나는 순간부터 켜진다. 처음 만날 때는 켜지지 않는다. 이 bit는 "슬레이트에서 이 tweet은 같은 작성자의 몇 번째 등장인가"를 표현한다.AUTHOR_NOT_ENGAGED_BY_VIEWER = 317: 후보의 author가 뷰어가 팔로우한 계정이 아니고, B의 positive-engagement set에도 없을 때 켜진다. 뷰어와 관계없는 새 작성자를 표시하는 bit다.HAS_SEMANTIC_IDS = 318: 후보에 semantic_ids가 배정돼 있을 때 켜진다.SID_L1_REPEAT_IN_SLATE = 319,SID_L2_REPEAT_IN_SLATE = 320: score 내림차순 순회에서 같은 SID L1(혹은 L2) prefix가 이미 슬레이트에 있으면, 두 번째 이후 후보에 켜진다.
- SID 배열에서 상위 코드만 안전하게 잘라 내는 helper가 새로 생겼다 확인(같은 커밋).
PostCandidate::semantic_id_prefix(levels: usize) -> Option<&[i32]>는 상위levels개 코드 슬라이스를 돌려주고,levels가 배열 길이보다 크면None을 돌려준다.
- 이 bit들은 후보별 기본 bitset과 합쳐진 뒤 압축돼 저장된다 확인(같은 커밋).
hydrate에서 후보별 base bitset에 slate-level bit set과 per-position bit set을 union으로 합치고, 압축해tweet_type_metricspayload로 저장한다.
- TweetTypeMetrics는 지금까지 랭킹 학습·서빙 로그와 오프라인 분석에 쓰이는 축이므로, 이제 슬레이트 다양성이 후보별 feature로 로깅되고 학습과 모델링에서 접근할 수 있게 된다. 다만 이번 커밋에는 이 bit들을 실제로 쓰는 학습 config 변경이 없어 연결만 열렸다. 실제로 쓰이는지는 후속 커밋에서 지켜볼 대상이다.
새로 알게 된 것D. 광고 웹 클릭 뒤의 구매 금액을 회귀로 예측하는 헤드가 proto에 생겼다
Phoenix proto에 광고 웹 클릭 뒤의 실제 구매 금액을 예측하는 continuous head와, 광고주별 구매 금액 baseline 메시지가 새로 생겼다 확인 —
phoenix/crates/serving/xai-recsys-proto/proto/recsys.proto(+9)- 헤드 이름은
ADS_WEB_CT_PURCHASE_VALUE = 5이고, 메시지 이름은PurchaseValueBaseline이다. - 함께 바뀐 파일은
phoenix/crates/serving/xai-recsys-proto/src/purchase_value.rs(114줄 신규)와phoenix/python/common/xai-proto/proto/recsys.proto(+9)이다.
- 헤드 이름은
새 헤드는
ContinuousActionNameenum의 다섯 번째 값이다 확인(같은 커밋).- 기존 4개는
DWELL_TIME = 1,CLICK_DWELL_TIME = 2,ACTIVE_SECS_5M_RESIDUAL_NORM = 3,BRIDGE_PROBABILITY = 4였다. ACTIVE_SECS_5M_RESIDUAL_NORM은 active seconds의 5분 이동평균 residual normalization이다. 이 세션의 다음 5분 활성 초를 이전 이동평균으로 정규화해 예측한다.BRIDGE_PROBABILITY는 부문 간 다리 확률이다.
- 기존 4개는
새
ADS_WEB_CT_PURCHASE_VALUE = 5는 웹 클릭-스루 컨버전 뒤 발생한 구매 금액의 회귀 target이다 확인(같은 커밋).- CT는 Click-Through의 약어이고, 여기서는 광고 클릭 뒤 랜딩 페이지에서 일어난 실제 구매를 말한다.
PredictNextActionsRequest요청 페이로드에 새 필드 23이 붙었다 확인(같은 커밋).repeated PurchaseValueBaseline purchase_value_baselines = 23; message PurchaseValueBaseline { int64 impression_id = 1; int64 advertiser_account_id = 2; double mean_value_usd_28d = 3; }- 각 baseline은
(impression_id, advertiser_account_id, 광고주의 최근 28일 평균 구매 금액 USD)튜플이다.
- 각 baseline은
Rust 헬퍼
purchase_value.rs가 baseline 검사와 조회 함수를 제공한다 확인(같은 커밋).is_valid_baseline은 id가 양수이고 USD 값이 양의 유한수인지 본다.find_baseline(request, impression_id, advertiser_account_id)도 함께 제공한다.
unit test 5개가 wire tag 안정성과 하위 호환성을 고정한다 확인(같은 커밋).
- wire tag: field 23 =
0xBA 0x01이고,returnLogitsListfield 22 =0xB0 0x01 0x01과 독립적이다. - 하위 호환성: 구 요청은 baseline 리스트가 빈 상태로 정상 디코딩된다.
- wire tag: field 23 =
의미 지금까지 광고 랭킹이 광고 클릭 확률만 예측해 그 확률에 광고주가 지불한 가격을 곱한 값을 광고 랭킹 스코어로 썼다면, 이 continuous head는 광고 노출과 클릭이 실제로 일으킬 구매 금액 자체를 예측한다. 여기서 광고 클릭 확률에는 2026-08-21 커밋(4세대+6)에서 신설된 conversion 액션 확률 헤드 20개도 포함된다.
광고주별 최근 28일 평균 구매액 baseline이 요청 페이로드로 함께 실려 오면, 그 baseline에 비해 이 impression이 얼마나 웃돌거나 밑돌지의 residual을 학습하고 서빙할 수 있다. 다만 금액이 직접 학습 target인지 baseline offset인지는 이번 커밋에 명시돼 있지 않다. 광고주별 평균 구매액에 비해 이 유저와 이 광고의 조합이 유독 큰(작은) 구매를 이끌 확률이 광고 랭킹 스코어에 들어가면서, X 광고 랭킹이 진일보한 value-optimizing 옥션 구조로 옮겨 갈 준비가 됐다 추정. 이는 Meta와 Google이 각각 VBB(Value-Based Bidding), tCPA/tROAS라고 부르는 것과 방향이 같다 추정.
baseline이 request마다 실려 온다는 것은 별도 오프라인 파이프라인이 광고주 계정의 28일 평균값을 매일 갱신해 광고 서빙 요청에 병렬로 넣어야 한다는 뜻이다. 서빙 트래픽 오버헤드가 걱정되므로 모든 광고주 계정의 baseline을 다 싣지는 않을 가능성이 높고, 요청 시점에 이 뷰어에게 진지하게 스코어링될 광고를 사전 pruning으로 고른 뒤 그 광고주들의 baseline만 붙이는 형태로 읽힌다 추정.
새로 알게 된 것E. H100 학습의 attention 커널이 GB300과 같은 CUTe DSL 계열로 통일됐다
H100 학습 설정의 attention 구현이 GB300과 같은 CUTe DSL 계열 커널로 바뀌었다 확인 —
phoenix/xrex/configs/xrecsys_two_tower.py(+1/−1)바뀐 값은
pallas_ranker_varlen_attn→cutedsl_ranker_varlen_attn이다._H100_OVERRIDES = { "bs_per_device": 480, "ep": 128, - "attn_impl": "pallas_ranker_varlen_attn", + "attn_impl": "cutedsl_ranker_varlen_attn", } _GB300_OVERRIDES = {"bs_per_device": 960, "ep": 64, "attn_impl": "cutedsl_ranker_varlen_attn"}
cutedsl_ranker_varlen_attn은 NVIDIA CUTLASS/CUTe DSL 기반 variable-length attention 커널이다. 이 커널은 4세대 공개(47c1bcd, 2026-08-13)부터_GB300_OVERRIDES에 있었다(xrecsys_two_tower.py:340). 4세대+17(49815da, 2026-09-08)에서는 SM80·SM90 forward·backward가 모두 오픈소스로 공개됐다(phoenix/xrex/cutedsl/ranker_fa4/).SM80 커널은 A100(compute capability 8.0)용이고 SM90 커널은 H100(9.0)용이며, GB300(10.3)은 arch 100 경로를 탄다 확인 — NVIDIA compute capability 표,
ranker_attention_fa4.py의cutedsl_arch.- 따라서 이번 전환으로 H100 학습은 SM90 커널을 쓴다. 두 GPU 세대가 같은
attn_impl이름을 쓰지만, 실제로 도는 커널은 세대마다 다르다.
- 따라서 이번 전환으로 H100 학습은 SM90 커널을 쓴다. 두 GPU 세대가 같은
seqpack(여러 유저 시퀀스를 한 배치 행에 이어 붙이는 패킹) 학습 config가 H100에서만
pallas_ranker_varlen_attn을 강제하는 제약이 이번 커밋으로 풀리는지는 확인하지 못했다. 이 제약은 4세대+11(bc8e5f0)에서 관측됐다.- seqpack 코드 경로에 명시된
NotImplementedError검사가 아직 남아 있다면, seqpack과 FA4(CUTe DSL 기반 flash attention v4) 조합은 여전히 막힌 상태다. 후속 커밋에서 지켜볼 대상이다.
- seqpack 코드 경로에 명시된
새로 알게 된 것F. Phoenix 학습의 Kafka 지표 내보내기 간격이 30초에서 120초로 늘었다
- Phoenix 학습의 Kafka OTel(OpenTelemetry) export 간격이 30s → 120s로 늘어, 지표 export 부하가 4배 완화됐다 확인 —
phoenix/xrex/data/streaming/kafkaloader.py(+2/−2)_init_otel_metrics의 defaultexport_interval_ms와PhoenixKafkaDataset.metrics_export_interval_ms가 둘 다 30_000 → 120_000으로 바뀌었다.
- 이 변경은 4세대+20(6bb4594, 2026-09-12)의 H 항목인 Kafka mTLS 연결과 짝으로 읽히지만, 방향은 반대다. mTLS는 인증 오버헤드를 늘리고, export 완화는 지표 부하를 줄인다.
- OTel 지표를 4배 덜 자주 내보내는 것은 학습 잡의 관측 tail 분해능을 내주고 collector 부담을 줄이는 트레이드오프다.
- 이번 완화는 지표 host cost가 실제로 부담이 됐다는 방증이다 추정.
새로 알게 된 것G. coordinated spam 필터가 root 팔로워 임계를 10k에서 30k로 올렸다
Grox(Grok 기반 nearline 주석 파이프라인)의 coordinated spam 필터 팔로워 임계가 10k → 30k로 올랐다 확인 —
grox/flows/reply_spam/task_filter.py(+1/−1)class TaskCoordinatedSpamFilter(TaskFilterWithPost): - FOLLOWER_COUNT_THRESHOLD_FOR_SPAM_DETECTION = 10000 + FOLLOWER_COUNT_THRESHOLD_FOR_SPAM_DETECTION = 30000Grox reply-spam 파이프라인에는 팔로워 임계가 두 개 따로 있다.
TaskSpamFilter·TaskReplyRankingFilter: 4세대 공개 이후 15k → 30k(4세대+1) → 40k(4세대+2) → 60k(4세대+3) → 80k(4세대+6) → 100k(4세대+7) → 120k(4세대+8) → 150k(4세대+17)로 일곱 번 올랐다 확인 —task_filter.py의 커밋별 값.- 스팸 분류는 root와 답글 대상 계정의 팔로워가 모두 임계 이하인 대화만 넣는다(77-93줄). 그래서 상향은 분류 범위 확대(더 큰 계정의 대화까지 검사)를 뜻한다.
TaskCoordinatedSpamFilter: 4세대 공개 때 1k였고, 5k(4세대+15)와 10k(4세대+17)를 거쳐 이번에 30k로 세 번째 올랐다 확인 — 같은 파일의 커밋별 값. coordinated spam은 여러 계정이 짝지어 같은 스팸 패턴을 반복 게시하는 유형이다.- 이 필터는 root 작성자의 팔로워가 임계 미만이면 건너뛴다(157-161줄, 사유
low_blast_radius). 그래서 상향은 작은 계정 아래의 대화를 판정에서 빼는 쪽이다.
두 임계는 모두 오르고 있고, 두 필터의 판정 범위도 모두 큰 계정의 대화 쪽으로 옮겨 간다 확인 — 같은 파일. 일반 spam 분류는 더 큰 계정의 대화까지 넓히고, coordinated spam 분류는 작은 계정 아래의 대화를 뺀다.
coordinated spam 판정의 비용을 노출이 큰 대화에 집중하려는 조정으로 읽힌다 추정. 근거는 건너뛰는 사유 이름이
low_blast_radius라는 점이다.
정본 반영 ../services/x.md의 4세대 공개 표에 4세대+21 행을 추가하고, 상세 절 ### 4세대+21 (2026-09-15, 2d4a03c) — …을 새로 만들었다. 광고 절, 피드백 신호 절, Phoenix 랭킹 절에도 새 continuous head와 슬레이트 관측 지표를 코드에 연결된 범위까지만 짧게 반영했다.
의미 슬레이트 다양성 관측과 광고 구매 금액 예측이라는 두 축이 나란히 열렸다. 구매 금액 축은 이번 커밋에서 연결만 됐고, 다양성 관측은 기본으로 요청의 5%에서 이미 돈다(위 A).
- 관측 범위가 슬레이트 다양성까지 넓어졌다. 지금까지 X 공개 코드의 스코어링 관측은 후보별 점수와 head별 확률까지였고, 슬레이트 층의 휴리스틱(DPP, author-decay, OON multiplier)이 후보 집합을 얼마나 바꾸는지는 계량되지 않았다.
- 이번 커밋의
pre_heuristic/top10/final세 stage 병렬 관측은 휴리스틱 층의 실제 영향 폭을 잴 수 있는 첫 연결이다. - 특히
pre_heuristic은 counterfactual("heuristic 없었다면")이므로, 다양성 개선과 랭킹 손실의 트레이드오프를 실측할 수 있게 한다. - 슬레이트 층 재편은 4세대+4의 slate context 파이프라인, 4세대+8의 VMRanker DPP 단순화, 4세대+20의 seed anchor pinning으로 이어져 왔다. 이번 관측은 그 계열의 관측 쪽 짝으로 읽힌다.
- 이번 커밋의
- 광고 랭킹이 확률 예측에서 금액 예측으로 넓어졌다.
- 2026-08-21 커밋(4세대+6)의 conversion 액션 20개는 여전히 확률(클릭·컨버전 발생 여부)을 예측하는 헤드였다.
- 새 continuous head는 금액 자체를 회귀 target으로 받는다. 광고주별 28일 baseline까지 요청에 함께 실어 residual 학습을 가능하게 하는 연결도 준비했다.
- value-optimizing 옥션은 광고주 ROI 최적화를 서빙 계층에서 직접 처리한다는 뜻이므로, 광고 랭킹 스코어 계산과 그 뒤의 옥션 로직 양쪽에 파급이 있을 것이다.
실제 소비(학습 config에서 새 bit와 head를 승격하는 일, 프로덕션 experiment ramp)는 후속 커밋에서 지켜볼 대상이다.
정본 반영 요약
정본은 services/x.md 하나만 고쳤고, 파이프라인 다이어그램은 그대로 뒀다.
- services/x.md의 4세대 공개 표에 행을 추가하고
### 4세대+21상세 절을 새로 만들었다. - 다이어그램은 다시 만들지 않았다. 파이프라인 구조(단계·소스·수치·세대)가 바뀌지 않았고, 이번 변경은 관측 side effect, proto 필드, attention 커널 전환이라
assets/x-pipeline.svg는 그대로 둔다.
검증에서 뒤집힌 것
뒤집힌 주장은 없다.
레이더
이번 배치에서는 arXiv cs.IR API가 계속 429(rate limit)로 응답해 triage를 하지 못했다. 재시도 6회 끝에 포기했고, 반영한 통과 항목도 0건이다.
다음에 볼 것
- 광고 구매 금액 헤드가 학습 config에 나타나는지 본다 — baseline offset regression인지 raw dollar regression인지가 여기서 갈린다.
phoenix/xrex/models/recsys_model.py나xrecsys_two_tower.py가ADS_WEB_CT_PURCHASE_VALUE를 continuous loss에 등록하는지,PurchaseValueBaseline이 실제로 어떤 shape로 서빙 배치에 붙는지 본다.
ResponseDiversityStatsSideEffect가 실제로 켜진 뒤의 실험 결과를 본다 — 5% 표본 데이터가 쌓이면 휴리스틱 층의 실제 다양성 개선과 랭킹 손실 폭이 어느 실험군에서 어떻게 갈리는지 볼 수 있다. 특히pre_heuristic과final사이의AuthorHhi·InNetworkShare·SidL1EntropyNorm차이를 본다.TweetTypeMetrics의 새 bit 12개(239-244, 315-320)가 학습 config에서 켜지는지 본다 — 슬레이트 문맥이 후보 feature로 들어가면 랭커가 슬레이트 인지형 스코어링으로 옮겨 간다(pointwise → slate-aware).- Phoenix
recsys_model.py의 feature list 갱신을 지켜본다.
- Phoenix
positively_engaged_author_ids의 action 18개가 랭킹 head 정의와 정확히 맞는지 본다 — 맞으면 이 세트가 유저 관계를 정의하는 canonical 상수가 된다.phoenix/runners.py의 positive engagement head 인덱스와 대조한다.
- coordinated_spam 임계 30k의 다음 값을 본다 — 일반 spam 임계처럼 계속 오르는지, 이번이 튜닝 노이즈였는지 가릴 수 있다.
조회 실패: arXiv cs.IR API — HTTP 429 (rate limit exceeded), 재시도 6회 후 포기.