0x00

리서치 / 일일 리포트

  • 읽은 자료 2건
  • 정본 반영 2개 파일
  • 레이더 1건
한 줄 요약X가 몰입형(immersive) 지면의 한 페이지를 강화학습으로 채우는 재순위기의 학습 코드를 공개했다. 보상은 체류 시간을 기준으로 하고, 서빙 스위치는 기본 off다.

오늘 함께 본 다른 변화는 다음과 같다.

  • X는 같은 커밋에서 홈믹서 미러의 좋아요와 관심 없음 가중치 2개를 똑같이 1.1배로 올렸다.
  • X는 브라질 선거 필터의 계정 목록을 결선 투표 관련 25개로 줄였다.
  • WeChat 검색의 생성형 retrieval WeGR이 여러 검색 지면에 배포됐다는 논문이 나왔다.

1페이지를 강화학습으로 채우는 재순위기의 학습 코드가 공개됐다 — X

자료 xai-org/x-algorithm@17c96bf — xAI 공개 저장소, 2026-10-14 03:41 UTC 커밋, 코드. 이 노트들은 4세대 공개 뒤의 X 커밋에 차례로 번호를 붙여 부르며, 이 커밋은 4세대+41이다. 바뀐 파일은 53개이고, diff 기준 약 +7,745/−6,964줄이다.

배경 X의 For You 피드에서는 랭킹 모델인 Phoenix가 후보마다 좋아요, 답글, 신고 같은 행동의 확률을 예측한다. 그 확률에 가중치를 곱해 더한 점수로 후보를 정렬한다. 그다음 VM-Ranker라는 별도 서비스가 DPP로 순서를 다시 조정한다. DPP(determinantal point process)는 비슷한 아이템이 함께 뽑히면 점수가 깎이도록 집합 단위로 고르는 다양성 기법이다. 이 방식은 아이템마다 점수를 따로 매기므로 "이 아이템을 몇 번째에 놓으면 유저가 페이지를 끝까지 볼까"라는 질문을 직접 다루지 못한다.

슬레이트(slate: 한 번에 보여 주는 아이템 묶음) 단위 강화학습은 이 질문을 다루는 방법이다. 정책(actor)은 슬롯을 하나씩 채운다. 가치 함수(critic)는 "이 시점부터 남은 슬롯에서 받을 보상의 합"을 예측해 정책을 개선한다. 이번 커밋은 X가 이 구조를 실제로 학습하고 있다는 것을 보여 주는 코드다.

새로 알게 된 것A. 재순위기는 체류 시간 보상으로 학습하는 페이지 디코더와 twin critic으로 이뤄진다

  • 몰입형 지면용 페이지 단위 RL 학습 config가 새로 생겼다 확인 — configs/xrecsys.py:388-417, 477-483.

    • 코드에서 이 재순위기의 이름은 page_rl이다.
    • config 이름은 immersive_page_rl이다. 홈 랭커 base에 page_rl=PageRlConfig(enabled=True)를 켠 것이다.
    • 학습 데이터용 Kafka 토픽도 user_action_sequence_immersive_page_rl로 따로 생겼다.
  • 재순위는 세 단계로 진행된다 확인 — page_rl.py:340-391, page_decoder.py:22-34.

    1. Phoenix 헤드 확률로 가중합 점수(behavior score)를 만든다.
    2. 상위 최대 48개를 후보 풀로 자른다(max_steps=48).
    3. 페이지 디코더가 첫 슬롯부터 하나씩 고른다(autoregressive 디코딩). 서빙에서는 12개 슬롯을 채운다(serve_steps=12).
  • 디코더가 각 단계에서 후보에 매기는 logit은 세 항의 합이다 확인 — page_decoder.py:85-119, 233-247.

    • 지금까지 고른 아이템을 attention으로 요약한 상태와 후보 임베딩의 내적
    • 풀 안에서 표준화한 behavior score(가중 1.0)
    • 이미 고른 아이템과 작성자가 같은지, SID(semantic ID: 아이템을 계층 코드로 표현한 것) 앞자리가 몇 단계 겹치는지에 음수 가중을 곱한 페널티
  • 보상은 슬롯별 체류 시간을 기준으로 한다 확인 — page_rl.py:51-59, 100-158.

    • 3초 이상 본 슬롯에 0.1 × min(체류초, 300) × (1 + min(참여 수, 3))을 준다.
    • 관심 없음·신고·차단·뮤트·덜 보기 중 하나라도 있으면 그 슬롯의 보상은 0이다.
    • 페이지의 모든 슬롯이 노출되고 마지막 슬롯에서 영상 품질 시청(VQV: video quality view)이 있으면 완주 보너스 1.0을 더한다.
    • 할인율 γ=0.8로 뒤쪽 슬롯 보상을 앞쪽으로 끌어와 return을 만든다.
    rewarded = impressed_mask & (dwell >= config.min_dwell_s)
    reward = jnp.where(rewarded, dwell_weight * dwell * mult, 0.0).astype(jnp.float32)
    

    — page_rl.py:121-122 (코드), 2026-10-14

  • critic은 두 개를 두고 둘 중 작은 값을 쓴다 확인 — page_critic.py:18-25, 121-139, 174-193.

    • twin critic이라 부르는 구성으로, 과대평가를 막는 관행이다.
    • 타깃은 TD(λ=0.9)이고, 탐색 트래픽에서 나온 페이지의 손실에 가중 9.0을 준다.
    • 다음 슬롯까지 넘겼는지를 맞히는 continuation 헤드도 함께 학습한다.
  • actor 손실은 네 항이다 확인 — page_decoder.py:37-48, 495-592, page_rl.py:80-88.

    • critic Q값에 기반한 advantage 항이다. behavior score 최고값과 0.6 이내인 후보만 대상으로 삼는다.
    • 기존 정렬 정책에서 너무 멀어지지 않게 하는 KL 항이다. 기존 정렬 정책은 behavior score의 softmax(τ=0.2)다. 목표 KL 0.35를 두고 계수 β를 0.1~3.0 사이에서 자동 조정한다.
    • 같은 작성자나 유사 SID를 연속으로 배치할 때 주는 페널티 항이다(가중 0.5).
    • 로그된 실제 노출 순서를 따라 하는 behavior cloning 손실이다(가중 0.25).
  • 서빙 디코딩은 temperature 값에 따라 두 방식으로 나뉜다 확인 — page_decoder.py:427-477.

    • temperature가 0이면 beam 4개를 만들고, critic 가치 합이 가장 큰 beam을 고른다.
    • temperature가 0보다 크면 Gumbel 샘플링으로 탐색한다.
  • behavior score 계산에는 홈믹서 미러와 다른 가중치가 config 기본값으로 따로 들어 있다 확인 — page_rl.py:62-77.

    • 홈믹서 미러는 For You 피드를 조립하는 home-mixer 서비스의 프로덕션 기본값을 크론으로 옮겨 적은 파일이다.
    • share 40.0, not_interested −500, report −1000처럼 홈믹서 미러(share 2.0, not_interested −52.272, report −234)와 크기가 크게 다르다.
    • 미러 주석이 없으므로 서빙값인지는 알 수 없다 추정.
  • 디코더를 서빙에 쓰는 스위치는 기본 off이고, home-mixer에서 디코더 출력을 쓰는 코드는 없다 확인 — inference/model_runner.py:3984.

    • 서빙 러너에 추가된 스위치는 serve_page_decoder: bool = False다.
  • 다만 학습 데이터에 이미 rl_rerank_prob·rl_decode_prob 같은 로그 확률 필드가 있으므로, 확률적 재순위가 일부 트래픽에서 이미 돌며 로그를 남기고 있다고 본다 추정.

    • off-policy 학습(서빙된 정책의 로그로 다른 정책을 학습하는 방식)에 쓰는 로그 확률은 실제로 서빙된 정책에서만 생긴다.

새로 알게 된 것B. 홈믹서 미러의 좋아요·관심 없음 가중치 2개가 똑같이 1.1배가 됐다

  • 홈믹서 미러에서 좋아요와 관심 없음 가중치가 바뀌었다 확인 — home-mixer/params/param.rs:320, 414-419.
    • 좋아요(FavoriteWeight): 0.6 → 0.66
    • 관심 없음(NotInterestedWeight): −47.52 → −52.272
    • 미러 sync 시각은 2026-10-13T16:00:30Z다.
  • 새 값은 둘 다 이전 값의 정확히 1.1배다. 09-29 커밋(4세대+31)의 NotInterestedWeight −43.2 → −47.52도 1.1배였다.
  • 10%씩 단계적으로 올리는 롤아웃 관행으로 보인다 추정. 같은 배율이 세 번 나왔다는 것 외에는 근거가 없다.
  • VM-Ranker 미러의 두 값은 바뀌지 않았다 확인 — vm-ranker/params.rs:3, 108-113.
    • favorite 0.5, not_interested −47.52 그대로다.
    • 두 미러가 갈라진 가중치가 5개가 됐다.

새로 알게 된 것C. 브라질 선거 필터가 결선 투표 관련 25개 계정으로 줄었다

  • 필터가 참조하는 계정 목록이 결선 투표 관련 25개로 줄었다 확인 — brazil_2026_election_filter.rs:17-74.

    • 필터 이름은 Brazil2026ElectionFilter다. 목록에 든 계정과 관련된 포스트를, 뷰어가 그 계정을 팔로우하지 않으면 피드에서 빼는 필터다.
    • 주석에는 브라질 선거법원(TSE)의 공문을 근거로 적었다.

    "Following the TSE’s Ofício GAB-PRES No. 4720/2026 and Despacho 3814449 (SEI proceeding No. 2026.00.000013846-8), on Oct 13, 2026 the list was reduced to the candidates in the Oct 25 runoff." — brazil_2026_election_filter.rs:17 (코드 주석), 2026-10-14

새로 알게 된 것그 밖의 변경

  • 홈 랭커 base에서 유저 설치 앱 피처를 껐다 확인 — configs/xrecsys.py:300.
    • 설정 값은 enable_user_installed_apps True → False다.
    • 어제 two-tower retrieval(유저 벡터와 포스트 벡터의 내적으로 후보를 찾는 구조)에서 끈 데 이어 랭커에서도 껐다.
  • VM-Ranker가 topic 요청(특정 주제 피드)에서는 기본으로 DPP를 건너뛴다 확인 — vm-ranker/scoring/mod.rs:85-87.
    • 새 스위치 TopicDppEnabled의 기본값이 false다.
  • 어제 신설된 retrieval 채널 하나의 후보 수를 요청마다 메트릭으로 기록하기 시작했다 확인 — sources/phoenix_source.rs.
    • 채널 이름은 ZERO_FAV이고, 좋아요 0개 포스트를 모으는 채널로 추정한다.
  • 다음 세 변경은 피드 동작과 직접 관계가 없다고 보고 읽지 않았다 추정.
    • abuse-enforcement(계정 집행 서비스) 리팩터다. diff가 약 7,900줄이다.
    • VF(visibility-filtering, 포스트마다 이 뷰어에게 보여도 되는지 판정하는 서비스)의 hydration 정리다.
    • FA4 attention 커널 변경이다.

정본 반영

  • services/x.md: 4세대+41 절을 새로 만들었다. 가중치 표의 favorite·not_interested 행을 갱신했고, 필터 절의 브라질 선거 필터 항목에 축소 사실을 추가했다. 열린 질문의 reward head 항목에는 학습 쪽 실체를 연결했고, 심층 분석 필요 항목을 추가했다. 출처 절에는 기준 sha 17c96bf를 추가했다.
  • topics/feed-diversity.md: X 케이스에 "5. 학습된 슬레이트 디코더" 절을 새로 만들었다. DPP 절에는 topic 요청에서 DPP를 생략한다는 사실을 추가했고, 누가 쓰는가 절을 갱신했다.

의미 이번 공개로 슬레이트를 RL로 생성하고 다양성 페널티의 크기를 체류 보상과 함께 학습하는 다음 단계가 학습 코드로 존재한다는 것이 확인됐다 확인. 이전 이해는 "X의 재순위는 점수순 정렬 + 작성자 감쇠 + DPP"였다. 서빙 스위치가 기본 off라서 기존 이해를 뒤집지는 않는다.

  • 보상은 참여 확률이 아니라 체류 시간에 참여 배수를 곱한 값이다 확인. 10-08의 CREAD 체류 손실과 10-13의 retrieval ld 헤드에 이어, 체류를 주 목적에 두는 흐름이 재순위 단계까지 이어졌다 추정.
    • CREAD는 체류 시간을 여러 임계값마다 넘었는지 이진 분류로 학습하는 방식이다.
  • 08-19 커밋(4세대+4)에 proto로만 나왔던 RewardOutputs·rewardRerankSlotProb의 쓰임새가 두 달 만에 학습 코드로 드러났다 추정. 근거는 이름과 로그 필드가 맞물린다는 정황이다.

↑ 목차

2WeChat이 SID 생성형 retrieval을 여러 검색 지면에 배포했다고 밝혔다 — 레이더

배경 생성형 retrieval은 아이템을 SID 토큰 열로 표현하고, 모델이 그 토큰을 순서대로 생성해 후보를 꺼내는 방식이다. 이 저장소는 레이더의 "생성형 retrieval / semantic ID" 스레드에서 이 계열의 프로덕션 진술을 모으고 있다. X도 10-02에 SID retrieval 서비스를 공개했다. 이번 논문은 WeChat의 산업용 검색 시스템에 쓰는 생성형 retrieval WeGR을 다룬다.

새로 알게 된 것

  • WeGR은 SID 토크나이저와 RL 방법을 묶었다 확인(초록).
    • SID 토크나이저 CoCo-VAE는 협업 신호를 넣고, codebook collapse(일부 코드만 쓰이는 현상)를 막는다.
    • RL 방법 DHPO는 SID 정확 일치에서만 보상이 나와 희소해지는 문제를, SID 계층별로 보상 범위를 넓혀 푼다.
  • 초록은 2개월 온라인 A/B 결과를 밝히고, 여러 검색 지면에 배포됐다고 적었다 확인(초록).
    • WeChat 전자상거래 검색에서 주문은 +2.539%, CTR은 +1.508%, 전환율은 +1.381%였고, CPU·GPU 사용량은 −25.5%·−26.1%였다.

정본 반영 정본에는 반영하지 않았다. radar.md의 생성형 retrieval / semantic ID 스레드에 추가 근거로 한 줄 넣었다.

의미 WeChat/Tencent에서 Tlow(flow 기반 아이템 토크나이저)에 이어 나온 두 번째 SID 프로덕션 진술이다. "SID 계층별 부분 보상"이라는 RL 설계 축도 추가한다. 다만 검색 지면이라 피드와 거리가 있다. 본문은 읽지 않았다.

↑ 목차

레이더

  • WeGR(WeChat, arXiv 2610.16979)은 SID 생성형 retrieval과 계층별 부분 보상 RL을 묶었고, 2개월 A/B에서 주문 +2.5%를 보고했다. radar.md의 SID 스레드에 추가했다.

↑ 목차

다음에 볼 것

↑ 목차

확인한 소스

  • X: 2026-10-14 이후 커밋은 17c96bf(2026-10-14 03:41 UTC) 1건이다. 릴리스는 없다.
  • Meta: engineering.fb.com RSS의 최신 글은 2026-10-13 GEM 글이고, 신규는 없다. ai.meta.com/blog의 최신 글은 2026-07이다.
  • Netflix: netflixtechblog.com RSS의 최신 글은 2026-09-25이고, 신규는 없다.
  • WebSearch 교차 확인("X For You algorithm update October 2026")에서는 1차 출처가 있는 새 발표가 나오지 않았다.
  • arXiv cs.IR: 30건을 파싱했고, 통과는 1건(WeGR)이다. 근접 탈락은 두 건이다.
    • Kwai Summary Attention V2는 Kuaishou 소속이지만 LLM KV cache 압축이라 추천과 무관하다.
    • HASTE는 SID 계층 손실을 다루고, 공개 벤치마크만 있다.
  • 목요일이라 산업 블로그 훑기는 하지 않았다.

↑ 목차