- 읽은 자료 1건
- 정본 반영 1개 파일
- 레이더 0건
1전역 인기 포스트 후보 소스가 기본으로 켜졌다 — X
자료 xai-org/x-algorithm@78460ca — xai-org, 2026-10-07T03:05:56Z, 코드. 파일 22개, +775/−681. 이 노트들은 4세대 공개 뒤의 X 커밋에 차례로 번호를 붙여 부르며, 이 커밋은 4세대+37이다. 직전 커밋은 2026-10-06의 e62790c(4세대+36)다.
배경 X의 For You 피드에서는 여러 후보 소스가 포스트를 모으고, Phoenix(Grok 기반 Transformer 랭커)가 행동 확률을 예측한 뒤, value model이 가중합으로 순서를 정한다. 후보 소스는 크게 팔로우한 계정의 글을 모으는 인네트워크 소스와 팔로우하지 않은 계정의 글을 모으는 OON(out-of-network) 소스로 나뉘며, 인네트워크에는 Thunder가, OON에는 Phoenix retrieval과 SimClusters 등이 있다. 2026-10-03에 생긴 PopularPostsSource는 유저와 무관하게 모두에게 같은 "최근 인기 포스트 500개" 목록을 OON 후보로 넣는 소스이고, 지금까지는 기본 off였다. 이번 커밋은 이 소스를 기본으로 켜고 새-작성자 부스트 가중치를 낮췄는데, 코드 구조보다 이 두 기본값 변경이 핵심이다.
새로 알게 된 것A. 인기 포스트 소스가 기본 경로에 들어왔고, 유저별로는 이미 본 포스트만 뺀다
home-mixer(For You 피드를 서빙하는 서비스) 미러에서 인기 포스트 소스를 켜는 플래그가 false에서 true로 바뀌었다 확인 —
home-mixer/params/param.rs:944-948.- 플래그 이름은
EnablePopularPostsSource다. - 미러 sync 시각은
2026-10-06T16:00:58Z다. home-mixer/params/param.rs는 X 내부 feature switch 기본값을 매일 미러링한 파일이다. 그래서 이 파일의 값 변경은 프로덕션 기본값이 바뀌었다는 신호로 읽는다.
- 플래그 이름은
소스가 켜지는 조건은 세 가지다 확인 —
home-mixer/sources/popular_posts_source.rs:27-31.- 캐시된 포스트를 재사용하는 요청이 아니어야 한다.
- 팔로우 전용(
in_network_only) 요청이 아니어야 한다. - 플래그가 켜져 있어야 한다.
유저별로 쓰는 정보는 이미 본 포스트 목록 하나뿐이고, 이 목록에 있는 포스트를 뺀다 확인(같은 파일 50행).
- 목록 이름은
seen_ids다.
- 목록 이름은
README에도 이 소스가 OON 소스로 처음 등재됐다 확인 —
README.md."
adds a shared list of popular recent posts."popular_posts_source"A shared list of popular recent posts, initially from the most-followed active accounts."
- "initially"라는 단서는 지금은 팔로워 상위 작성자에서만 뽑지만 범위를 넓힐 수 있다는 뜻으로 읽힌다 추정. 근거는 2026-10-06 커밋(4세대+36)의 잡 코드가 작성자 집합을 BigQuery 스냅샷에서 고르는 구조라 교체가 쉽다는 점이다.
목록을 만드는 방식은 어제와 같다.
- 최근 7일 안에 활동한 작성자 가운데 팔로워 상위 0.005%의 원본 포스트를 모은다 확인(2026-10-06 커밋 4세대+36,
home-mixer/popular_posts_job.rs). - 24시간 안의 조회수를 반감기 8시간 가정으로 24시간 누적 조회수로 외삽해, 상위 500개를 고른다 확인(같은 파일).
- 최근 7일 안에 활동한 작성자 가운데 팔로워 상위 0.005%의 원본 포스트를 모은다 확인(2026-10-06 커밋 4세대+36,
새로 알게 된 것B. home-mixer 미러의 새-작성자 부스트 가중치가 0.02에서 0.015로 내려갔다
- 새-작성자 부스트 가중치가 home-mixer 미러에서 0.02 → 0.015가 됐다 확인 —
home-mixer/params/param.rs:384-388.- 새-작성자 부스트(
post_unexplored)는 노출이 1,000회 미만인 작성자의 인네트워크 포스트에 점수를 더해 주는 콜드스타트 장치다. - 가중치 이름은
PostUnexploredWeight다.
- 새-작성자 부스트(
- 같은 이름의 파라미터가 VM-Ranker(home-mixer가 점수 정제를 맡기는 별도 서비스)의 미러에도 있는데, 그쪽은 0.02 그대로다 확인 —
vm-ranker/params.rs:91-95. - home-mixer는 2026-09-24 커밋(4세대+28) 이후 로컬 가중합을 먼저 계산하고 VM-Ranker RPC로 점수를 정제하며, RPC가 실패하면 로컬 점수를 서빙한다 확인(정본 4세대+28 항목).
- 따라서 0.015는 최소한 RPC 실패 경로의 값이고, 정상 경로의 최종값이 어느 쪽인지는 이 커밋만으로 판단할 수 없다 추정. 두 미러가 다른 피처 스위치 키를 읽는지 아직 대조하지 않았으므로 추정으로 둔다.
새로 알게 된 것C. 검색 랭킹 학습에서 negative 샘플의 렉시컬 매치 피처를 바로잡는 코드가 들어왔다
Phoenix는 For You뿐 아니라 검색 결과 랭킹도 학습한다. 학습할 때 실제 노출 기록만으로는 "관련 없는 결과"가 부족해서, 배치 안 다른 유저의 데이터를 빌려 가짜 negative를 만든다. 이것을 in-batch negative sampling이라고 부른다.
- 검색 쿼리가 있는 배치에서는 negative를 두 종류 만든다 확인 —
phoenix/xrex/data/recsys/recsys_batch.py의apply_negative_sampling.- 다른 유저가 본 포스트를 내 쿼리와 짝짓는다.
- 내가 본 포스트를 다른 유저의 쿼리와 짝짓는다.
- 두 쿼리의 임베딩 코사인 유사도가 0.9 이상이면 비슷한 쿼리로 보고 버린다.
- negative에는 "읽지 않고 지나감" 라벨(
ClientTweetRecapNotDwelled)이 붙는다.
- 문제는 포스트 피처를 원래 슬롯에서 전부 그대로 복사한다는 점이다. 2026-09-18 커밋(4세대+24)에 들어온 렉시컬 매치 피처 두 개는 원래 쿼리 기준 값인데, 새 쿼리와 짝지은 negative에도 그대로 남아 있었다 확인(복사 코드 1391-1425행).
exactPhraseSeq는 쿼리 문구가 포스트에 그대로 있는지를 나타낸다.matchedWordFractionSeq는 쿼리 단어 가운데 포스트에 나오는 단어의 비율이다.
- 이번 커밋은 신규 파일 하나로 이를 고친다 확인 —
negative_word_match.py(51줄).- 호출부는
recsys_batch.py:1476-1488이다. search_negative_clear_word_match를 켜면 negative 슬롯의 두 피처를 0(값 없음)으로 지운다. 이 플래그는 기본 False다.- 학습 데이터에 새 컬럼 세 개가 있으면, 외부 라이브러리
xai_search_lexical_match로 새로 짝지어진 쿼리 기준 값을 다시 계산한다.lexicalTextSeq: 포스트 본문lexicalQuerySeq: 쿼리lexicalAuthorSeq: 작성자
- 호출부는
- 교정 전에는 특히 2번 negative가 "쿼리와 문구가 정확히 일치한다"는 피처를 가진 채 비관련 라벨을 받았다. 모델은 렉시컬 매치 피처를 실제보다 덜 믿도록 학습됐을 것이다 추정. 근거는 피처와 라벨이 체계적으로 어긋나는 구조라는 점이다.
새로 알게 된 것그 밖의 변경
- Transformer 각 층의 출력 크기를 손실에 더하는 정규화 옵션이 생겼고, 기본값은 0이다 확인 —
recsys_model.py:664, 3827-3830.- 옵션 이름은
per_layer_l2_weight다. attention 출력과 FFN 출력의 크기(제곱 평균)를 더한다. - 활성값이 층을 지나며 커지는 것을 억제하려는 장치로 보인다 추정.
- 손실 입력을 만드는 함수 4개가 하나로 합쳐진 리팩터링도 있었다.
- 옵션 이름은
- VF(visibility filtering, 노출 가능 여부를 판정하는 안전 계층)는 이제 포스트 저장소가 찾지 못한 포스트를 판정하지 않고 실패로 처리한다 확인 —
visibility-filtering/evaluate_tweets.rs.- 포스트 저장소는 tweetypie이고, 이 저장소가 "찾을 수 없음"을 돌려준 포스트가 대상이다.
정본 반영 services/x.md와 파이프라인 그림을 고쳤다.
- 후보 생성 절 소스 표의
PopularPostsSource행에서 게이트를 "기본 off"에서 "4세대+37에서 기본 on"으로 고치고, 활성 조건을 추가했다. - 랭킹 절의 새-작성자 부스트 표와 가중치 표, 콜드스타트 절에서
PostUnexploredWeight값을 home-mixer 0.015, VM-Ranker 0.02로 함께 적었다. ### 4세대+37절을 새로 만들고, 출처 절에 기준 커밋78460ca를 추가했다.assets/x-pipeline.svg의 SimClusters 상자 부제에 "인기 목록 on(10-07)"을 추가했다.
의미
- 4세대 공개 이후 X의 OON 후보는 모두 유저 임베딩이나 클러스터 같은 개인화 입력에서 나왔다. 이번에 처음으로 모든 유저에게 같은 목록을 주는 소스가 기본 경로에 들어왔다 확인.
- 다만 이 소스는 후보일 뿐이고, 실제 노출은 Phoenix 랭킹이 결정한다 추정. 근거는 소스가 점수 없이
PostCandidate만 만든다는 점이다.
- 다만 이 소스는 후보일 뿐이고, 실제 노출은 Phoenix 랭킹이 결정한다 추정. 근거는 소스가 점수 없이
- 같은 날 인기 작성자 쪽 후보는 늘리고, home-mixer 미러의 신규 작성자 부스트 가중치를 25% 낮췄다(VM-Ranker 미러는 그대로다). 두 변경이 하나의 실험인지는 코드로 확인할 수 없다 추정.
- 검색 negative 교정은 플래그가 기본 off라 당장은 학습에 영향이 없다 확인.
- 그러나 2026-09-18 커밋(4세대+24)에서 렉시컬 피처를 추가한 지 3주 만에 학습 데이터 쪽 결함이 드러났다는 점은, 검색 랭커가 이 피처를 아직 제대로 쓰지 못했을 수 있음을 뜻한다 추정.
다음에 볼 것
- 두 미러의 새-작성자 부스트 가중치가 다른 문제를 확인한다 — home-mixer 0.015와 VM-Ranker 0.02 중 정상 경로의 최종값이 어느 쪽인지, vm_ranker RPC가 로컬 가중치를 덮어쓰는지 본다.
- 가중치 이름은
PostUnexploredWeight다.
- 가중치 이름은
PopularPostsSource의 성과 신호를 추적한다 — 2026-09-24 커밋(4세대+28)에서 생긴Phoenix.RetrievalContribution계열 메트릭에 이 소스가 잡히는지, served_type이 별도로 분리되는지 본다. 현재 라벨은ForYouPhoenixRetrieval이다.search_negative_clear_word_match의 기본값이 바뀌는지 지켜본다 — 켜지면 검색 랭커 학습 데이터가 바뀐다.- X VF의
NOTICE등급을 심층 분석한다 — 10-07에서 넘어온 항목이고, 아직 풀리지 않았다.
소스 점검 메모
이번 실행에서 점검한 세 출처 모두에서 반영할 새 자료를 찾지 못했다.
- Meta: engineering.fb.com 최신 글은 2026-10-06 "NTS: Authenticated Time at Meta"(시간 동기화 인프라)로, 피드와 무관해 건너뛰었다. ai.meta.com/blog에는 피드·추천 관련 신규 글이 없었다.
- Netflix: netflixtechblog.com 최신 글은 2026-09-25로, 신규가 없다. research.netflix.com은
/publications가 계속 404지만, 첫 페이지와/research-area/recommendations는 열린다. 첫 페이지의 출판물 최신 날짜는 2026-02-24로, 신규 0건을 확인했다. 다음부터는 이 두 경로로 확인한다. - arXiv cs.IR: 30건을 파싱했고, 수용 기준을 통과한 것은 0건이다. 생성형 retrieval의 Semantic ID(아이템을 계층 코드로 표현한 토큰 열) 연구가 여러 건 있었다: 2610.08732, 2610.07402, 2610.06590. 하지만 모두 플랫폼 기업 저자나 프로덕션 근거가 없다.