피드 다양성 — 점수순 정렬을 일부러 망가뜨리는 레이어
최종 갱신: 2026-08-09
랭커 점수대로만 정렬하면 같은 작성자·같은 주제·같은 영상이 연달아 나온다. 그걸 막는 레이어. 크게 다섯 가지 방식이 있고, 대부분의 서비스가 여러 개를 겹쳐 쓴다.
- 감쇠 (decay) — 같은 키(작성자 등)의 n번째 아이템 점수에
f(n) < 1을 곱한다. 순수 pointwise, 싸다. - 탐욕 재순위 (MMR) — 이미 뽑은 것들과의 거리를 점수에 더한다. 리스트 상태에 의존한다.
- 슬레이트 최적화 (DPP) — 집합 전체의 행렬식을 최대화한다. 제일 비싸고 제일 원리적이다.
- 중복 제거 (dedup) — 같은 것을 두 번 안 보여준다. 다양성이라기보다 위생.
- 분포 보정 (calibration) — 리스트의 장르·주제 분포를 유저 이력의 분포에 맞춘다. "서로 다르게"가 아니라 "이력과 비율이 같게" — 목표 자체가 다르다. Netflix가 수식을 공개했다(아래).
단, 이 목록으로 서비스를 비교하려면 먼저 "공개됐는가"를 봐야 한다. X는 네 가지가 전부 소스코드로 읽히는데 Meta는 주요 피드에 대해 넷 중 어느 것도 알고리즘 수준으로 공개한 적이 없다. [추정] — 아래 "케이스: Meta" 절에 검사한 코퍼스를 적었다. 그 부재 자체가 이 노트의 두 번째 발견이다.
케이스: X — 네 개를 다 쓴다
1. 작성자 다양성 감쇠 (2026)
fn diversity_multiplier(decay_factor: f64, floor: f64, position: usize) -> f64 {
(1.0 - floor) * decay_factor.powf(position as f64) + floor
}
[확인] — home-mixer/scorers/ranking_scorer.rs:186-188
position은 점수 내림차순으로 정렬한 뒤 같은 작성자 안에서 몇 번째인가다. 최종 피드에서의 위치가 아니다. [확인] — :198-214
설계 포인트 두 가지:
floor가 있다.decay^n만 쓰면 같은 작성자의 10번째 포스트가 0에 수렴해 사실상 금지된다. floor를 두면 아무리 많아도 원래 점수의floor배는 남는다. 즉 작성자당 상한이 아니라 페널티다.decay_factor와floor값은 FeatureSwitch에 있고 레포에 없다.[확인]—AuthorDiversityDecay,AuthorDiversityFloor
2025 Scala 세대에는 이 감쇠기가 별도 스코어러 파일로 존재했다가(author_diversity_scorer.rs) 2026에서 랭킹 스코어러 안으로 흡수됐다 [추정] — 2026 레포에 author_diversity_scorer.rs가 남아 있지만 scorers/mod.rs에 선언되지 않아 모듈 트리에서 연결이 끊겨 있다 [확인].
2. MMR — 2025 Scala
score = relevance + diversityWeight × minDistance(후보, 이미 선택된 것들)
[확인] — DiversityRescoringFeatureHydrator.scala:102. 임베딩 차원 128 [확인] :32. 거리는 코사인 유사도가 아니라 L2 정규화한 임베딩 사이의 L2 거리다 [확인] :64-69.
상위 구간에는 다양성이 아예 안 걸린다. minDistance는 조건부다:
if (selected.isEmpty || selected.size < (1 - diversityRatio) * n) None // → getOrElse(2.0)
[확인] :92-93,102. 즉 기본값 2.0은 "첫 후보일 때"만이 아니라 리스트 앞의 (1-diversityRatio)×n개 전부에 적용된다. 상수 2.0이 모두에게 똑같이 더해지므로 그 구간은 순수 relevance 순서 그대로다. 다양성은 꼬리에만 건다.
ScoreFeature를 통째로 덮어쓴다. [확인] :28,70,91 — relevance를 ScoreFeature에서 읽어 같은 자리에 되쓴다. 즉 이 시점 이후 "랭커 점수"라고 부르는 값은 이미 다양성이 섞인 값이다.
같은 세대에 카테고리 버전이 따로 있다. SimClusters 카테고리 카운트 기반 탐욕 페널티:
penalty += math.log(cnt + 1) / math.log(2) // log2(cnt+1)
score = math.max(relevance - weight * penalty, 0.00001)
[확인] — CategoryDiversityRescoringFeatureHydrator.scala:69,72
MMR은 더하고 카테고리는 뺀다. 전자는 "다른 것에 보상", 후자는 "같은 것에 벌점"이다. 같은 파이프라인에 둘 다 param-gated로 들어가 있다(TwhinDiversityRescoringParam :589-590, CategoryDiversityRescoringParam :593-594). [확인] — ScoredTweetsRecommendationPipelineConfig.scala:580-601
둘 다 켜지면 겹쳐 쓴다. 카테고리 쪽이 relevance로 읽는 ScoreFeature는 이미 MMR이 덮어쓴 값이다. 서로 독립적인 두 보정이 아니라 직렬로 합성된다. [확인] — 위 A4의 in-place 덮어쓰기
순서 문제: 이 둘은 postSelectionFeatureHydration이라는 이름의 단계에 실려 있어 top-K 자르기 이후에 도는 것으로 보인다 [추정]. 근거는 단계 이름과 resultSelectors(:574-577, DropRequestedMaxResults 포함) 뒤에 배치됐다는 것뿐이다 — 레포에 벤더링된 product-mixer/core의 RecommendationPipelineConfig.scala는 resultSelectors(:136) → postSelectionFilters(:142)만 정의하고 postSelectionFeatureHydration이라는 훅 자체가 없다. 즉 실행 위치를 코드로 확인할 수 없다. [확인](부재) — grep -r postSelectionFeatureHydration product-mixer/ → 0건
3. DPP — 2026, 별도 서비스
VMRanker가 gRPC로 외부 서비스를 호출하고, 응답 점수로 기존 점수를 덮어쓴다. [확인] — home-mixer/scorers/vm_ranker.rs:47-52
let dpp_params = if dpp_theta > 0.0 || dpp_max_selected_rank > 0 {
Some(DppParams { theta: dpp_theta, max_selected_rank: dpp_max_selected_rank })
} else { None };
[확인] — vm_ranker.rs:112-120. theta는 관련성-다양성 트레이드오프, max_selected_rank는 DPP를 적용할 상위 구간 길이로 보인다 [추정] — 이름과 DPP 관행에 근거하며 코드에 설명은 없다.
서비스 본체는 공개되지 않았다. 레포에 있는 건 클라이언트와 proto 매핑뿐이라, 실제 커널 행렬을 무엇으로 만드는지는 알 수 없다. [확인] — repo-wide, xai_vm_ranker_proto는 외부 크레이트
실패 시 조용히 사라진다. gRPC가 실패하면 모든 후보에 Err를 반환하는데, 파이프라인의 update_all은 Err를 로그도 없이 건너뛴다.
fn update_all(&self, candidates: &mut [C], scored: Vec<Result<C, String>>) {
for (candidate, scored) in candidates.iter_mut().zip(scored) {
if let Ok(scored) = scored { self.update(candidate, scored); }
}
}
[확인] — candidate-pipeline/scorer.rs (update_all 기본 구현), vm_ranker.rs:33-38
→ VMRanker가 죽으면 다양성 최적화 없이 순수 점수순 피드가 나가고, 응답에는 아무 표시가 없다. fail-open이며 관측하려면 별도 지표가 필요하다.
EnableVMRanker FeatureSwitch로 통째로 꺼진다. [확인] — vm_ranker.rs:18-20
4. 중복 제거 — 실제로는 여기가 제일 촘촘하다
2026 필터 [확인] home-mixer/filters/:
drop_duplicates_filter / retweet_deduplication_filter / dedup_conversation_filter
2025 Scala는 dedup 필터만 6종이고, 각각 발동 조건이 좁다 [확인]:
| 필터 | 규칙 | 위치 |
|---|---|---|
RetweetDeduplicationFilter |
후보 풀의 비(非)리트윗 전부를 먼저 seen에 넣고, 리트윗은 자기 id 또는 원본 id가 seen에 있으면 제거 | :27-36 |
MediaIdDeduplicationFilter |
미디어가 정확히 1개인 후보만 대상. 다중 미디어는 손도 안 댄다 | :26,33-35 |
ClipClusterDeduplicationFilter |
클러스터가 1종일 때만. Map[Long,Long]의 distinct 값 개수라 이미지 4장이 같은 클러스터면 이것도 걸린다 |
:24-27,29 |
DuplicateConversationTweetsFilter |
조상 제거 후 같은 루트의 답글은 maxBy(ScoreFeature) 하나만. 루트가 없는(대화 아닌) 후보는 전부 통과 |
:33-40 |
QuoteDeduplicationFilter |
인용된 원본 쪽을 지운다 (인용 포스트가 아니라) | :23-26, 배선 :603,609 |
KeepTopKCandidatesPerCommunity |
커뮤니티당 1개 + 전체 커뮤니티 후보 3개 상한 (MaxCandidatesPerCommunity = 1, MaxCommunityCandidates = 3) |
:14-15,30,32 |
MediaIdDeduplicationFilter의 if (mediaIds.size == 1) 조건은 의도적 보수성으로 보인다 — 이미지 4장짜리 포스트 두 개가 한 장만 겹칠 때 지우면 과하다 [추정]. 코드에 이유는 없다. (파일명은 MediaDeduplicationFilter.scala인데 object명은 MediaIdDeduplicationFilter다 [확인].)
QuoteDeduplicationFilter의 방향은 직관과 반대다. "인용 중복 제거"라고 읽으면 인용 포스트를 지울 것 같지만, 실제로는 인용당한 원본을 피드에서 뺀다 — 인용문이 원본을 이미 포함해 보여주기 때문 [추정].
tweet-mixer 쪽에는 저신호 유저 전용으로 작성자당 1개 규칙이 따로 있다. DropDuplicateCandidates(duplicationKey = _.features.getOrElse(AuthorIdFeature, None)) [확인] — HomeRecommendedTweetsRecommendationPipelineConfig.scala:364
케이스: Meta — 주요 피드에 대해서는 아무것도 공개하지 않았다
이건 우리 조사의 구멍이 아니라 발견이다. Meta는 지면별 AI system card 30종, DSA 리스크 평가 문서, 엔지니어링 블로그를 계속 내면서 예측 헤드 이름·개별 피처 문장·단계별 후보 수·가중치를 정하는 방법까지 공개했는데, 다양성과 dedup만은 알고리즘 수준으로 한 번도 쓰지 않았다. X 쪽에서 감쇠 함수 형태, MMR 수식, dedup 필터 6종의 발동 조건이 줄 단위로 읽히는 것과 대비된다.
Meta 주요 피드에서 얻을 수 있는 다양성 서술은 아래가 전부다.
| 지면 | 공개된 문장 전부 | 등급 |
|---|---|---|
| Facebook Feed | pass 2 = "the contextual pass. Here, contextual features, such as content-type diversity rules, are added to help diversify Juan's News Feed." (2021) + "tries to ensure that your Feed has a balanced mix of content types. That means, for example, you wouldn't see multiple video posts in a row" (카드) | [확인] |
| Instagram Feed | "The system also tries to ensure your feed has a balanced mix of content types." — Facebook 문장보다 오히려 덜 구체적이다 | [확인] |
| Instagram (Mosseri) | "we try to avoid showing too many posts from the same person in a row, or too many suggested posts back to back" | [확인] |
| Instagram Explore | *"in case we would like to increase the diversity of results, we might shuffle items based on some business rules (e.g., 'Do not show items from the same authors in a sequence')"* — Meta 유기 지면에서 유일하게 규칙을 예시로 든 문장이다. 다만 *"in case we would like to"*라 실제 발동 여부는 미확정 | [확인] |
| Threads | 한 문장도 없다. "multiple video posts in a row" 수준의 서술조차 없다 | [관찰] 2026-08-09 (ig-threads-feed 카드 본문 1건) |
[확인] 순서대로 — engineering.fb.com, 2021 · fb-feed 카드 · ig-feed 카드 · Instagram Ranking Explained, 2023 · Scaling the Instagram Explore recommendations system, 2023 · ig-threads-feed 카드
알고리즘 이름(MMR/DPP), 감쇠 함수, 임계값 N, dedup 규칙 — 전부 no primary source found. [추정] — 검사한 코퍼스는 위 표의 1차 출처 6건과 Transparency Center 시스템 카드 15종, engineering.fb.com·ai.meta.com·about.instagram.com 본문(2026-08-09 열람)이다. 미공개 자료까지 없다는 근거는 아니다. 작성자 다양성만 예외다 — Explore가 *"same authors in a sequence"*를 예시로 들었다(위 표). ⚠ 그리고 Instagram 알림 블로그(2025)는 *"maximal marginal relevance (MMR)"*를 이름으로 부른다 — 피드가 아니라 알림이므로 위 부재 주장의 범위는 피드 지면 한정이다. [확인]
알 수 있는 것은 위치뿐이다: 다양성은 pass 2, 즉 포인트와이즈 스코어링이 끝난 뒤 별도 패스에 붙는다 [확인] 2021. [추정] X가 MMR·DPP를 선택 이후 단계에 두는 것과 구조적으로 같은 자리다. listwise가 존재한다는 진술도 있다 — "pointwise and listwise predictions" + "personalized methodology for delivery frequency control to optimize for long-term user value" [확인] ai.meta.com, 2023. 형태는 미공개.
다만 Facebook은 다양성을 랭킹 피처로도 쓴다
카드에 대응 피처가 실재한다 [확인] fb-feed: "Number of times you have seen posts with the same content type (e.g. video, photo, etc) as the current post in the past hour"
→ 같은 다양성 개념이 재순위 규칙이자 동시에 랭킹 입력이다. X 쪽은 이 저장소가 기록한 범위에서 다양성이 전부 사후 점수 조작(감쇠·MMR·DPP·dedup)이고 "최근에 같은 유형을 몇 번 봤나" 계열 랭커 피처가 등장하지 않는다 — 다만 X 랭커의 전체 피처 목록을 훑어 확인한 것은 아니라 [추정]이다. 확인하면 이 대조가 서거나 무너진다 → 아래 "아직 확인 못한 것".
유일한 예외 — Instagram 알림의 곱셈 페널티 (2025)
Meta 전체에서 가장 기계적인 다양성 공개이고, 피드가 아니라 알림이다.
Score(c) = R(c) × D(c)
D(c) = ∏_{i=1..m} (1 - w_i · p_i(c))
p_i(c) = max_{h ∈ H} sim_i(c, h)
출처: A New Ranking Framework for Better Notification Quality on Instagram, 2025-09-02
⚠ 위 세 줄은 verbatim 인용이 아니다. 원문에서 이 수식들은 LaTeX 이미지(latex.php?latex=…)로 렌더링돼 있어 본문 텍스트로 존재하지 않는다. 위 표기는 그 이미지를 보고 옮겨 적은 것이다. [관찰] 2026-08-09 (글 본문을 받아 수식 자리가 전부 이미지 태그임을 확인)
다만 각 구성요소는 이미지가 아닌 본문 산문이 그대로 뒷받침한다 [확인] 같은 글:
- 곱셈 결합 — "the product of its base ranking score and a diversity demotion multiplier"
- "R(c) represents the candidate's base relevance score"
- "D(c) ∈ [0,1] is a penalty factor that reduces the score based on similarity to recently sent notifications"
- "sim_i(·,·) is a predefined similarity function for dimension i"
→ [추정] 곱 기호와 max 연산자의 정확한 형태만 이미지 의존이고, 나머지(곱셈 구조·R·D의 정의·비교 대상이 최근 발송 이력이라는 점)는 텍스트로 확인된다. 아래 해석은 그 텍스트 위에 선다.
R(c)= base relevance,D(c) ∈ [0,1]= 페널티,H= 최근 발송 이력,w_i ∈ [0,1]= 차원별 강도,τ_i= 유사도 임계값- 베이스라인 구현에서
p_i(c)는 "equals 1 if the similarity exceeds a threshold τ_i and 0 otherwise" — 연속 유사도가 아니라 계단 함수 - 차원 4종: content / author / notification type / product surface
X의 두 형태와 나란히 놓으면 셋이 전부 다르다.
| 비교 기준 집합 | 방향 | 결합 | |
|---|---|---|---|
| X 2025 MMR | 이 요청에서 이미 선택된 후보들 | 거리에 보상 | 덧셈 |
| X 2025 카테고리 페널티 | 이 요청의 카테고리 카운트 | 같은 것에 벌점 | 덧셈 |
| IG 2025 알림 | 최근 발송 이력 H (요청 밖) |
유사한 것에 벌점 | 곱셈 |
두 가지가 특히 중요하다.
- 기준 집합이 다르다. X의 MMR은 슬레이트 안에서 후보끼리 비교하고, Instagram 알림은 과거에 이미 보낸 것과 비교한다.
[추정]알림은 슬레이트가 아니라 시간축 위의 단건 스트림이라 비교 대상이 이력일 수밖에 없다. - 곱셈이라 거부권이 된다.
w_i = 1이고 유사도가 임계를 넘으면D(c) = 0, 점수가 통째로 0이다. X의 덧셈형은 페널티가 아무리 커도 relevance가 이길 수 있고 카테고리 쪽은max(…, 0.00001)로 바닥까지 둔다[확인]. 곱셈 페널티 = hard veto라는 성질은 Instagram 2020 value model과 같은 성격이다 → multi-task-ranking.md.
retrieval 단계 다양성 — Instagram은 여기가 주력일 수 있다
[확인] Designing a Constrained Exploration System, 2020 — retrieval DSL에 diversify_by(seed_id, method=round_robin) 한 줄이 있다. seed 계정 단위 라운드로빈이고, 같은 쿼리의 max_media_per_account=10도 같은 성격이다.
[추정] Instagram의 다양성은 랭킹 후 재배열보다 후보 생성 단계에서 미리 섞는 쪽이 주력일 수 있다 — 랭킹 후 서술은 "too many" 수준인데 retrieval 쪽은 메서드 이름과 파라미터 값이 나온다. X도 tweet-mixer의 라운드로빈 위브와 저신호 유저 작성자당 1개 dedup을 retrieval 단계에 두므로 rung 자체는 공통이다 → candidate-allocation.md.
디벙크 — "Instagram은 같은 계정 3연속을 막는다"
널리 반복되지만 Meta 1차 출처를 찾지 못했다. [추정] — 검사한 코퍼스는 위 절과 같다(카드 15종 + Meta 블로그 3계열, 2026-08-09 열람). Mosseri의 실제 문장에 숫자가 없다는 것만은 실측이다 [관찰] 2026-08-09 (아래 인용 글 본문 1건).
[확인] Instagram Ranking Explained, 2023-05-31: "we try to avoid showing too many posts from the same person in a row, or too many suggested posts back to back"
- "too many" → 임계값 없음. "try to avoid" → 하드 제약도 아님. "3"이라는 숫자를 Meta 문서에서 찾지 못했다
[추정](같은 코퍼스). - 같은 문장이 서로 다른 두 제약을 말한다: (a) 동일 작성자 연속, (b) suggested(비연결) 포스트 연속. (b)는 Facebook 쪽에 대응 서술이 없다.
- 아이러니: "3"이라는 상수가 실제로 코드에 있는 쪽은 X다.
MaxCandidatesPerCommunity = 1/MaxCommunityCandidates = 3[확인]. 작성자 다양성도 X는 함수 형태((1-floor)·decay^n + floor)까지 읽히고 계수 값만 없다. [추정]이 오해의 형태는 X의 "인네트워크 50:50"과 같다 — 정성적 문장 하나가 유통 과정에서 구체적 상수로 굳는다. 같은 절 → candidate-allocation.md.
케이스: Netflix — 다양성의 단위가 리스트가 아니라 페이지다
X·Meta와 지면 구조가 달라서(단일 스트림이 아니라 행×열 2차원 홈) 다양성이 걸리는 위치도 다르다.
다양성이 재순위 레이어가 아니라 행 선택 단계에 있다. 회원당 후보 행 수만 개에서 약 40개를 고를 때 *"관련성과 다양성으로 최적화"*한다 [확인] TMIS 2015. 2015년부터 템플릿을 버렸기 때문에("BYW 행이 하나도 없는 홈도, 절반이 BYW인 홈도" 허용) 다양성은 아이템 순서 조작이 아니라 페이지 구성 문제다. X의 MMR·DPP가 "정렬된 리스트를 어떻게 흔들까"라면 Netflix는 "어떤 렌즈(행)들을 나란히 놓을까"다.
calibration — 다섯 번째 방식의 1차 출처. Steck, Calibrated Recommendations (RecSys 2018): 유저가 로맨스 70%/액션 30%를 봤으면 추천 리스트도 그 비율을 유지하도록 KL-divergence 페널티로 탐욕 재순위한다. MMR과 형태는 같은 탐욕 재순위인데 **목표가 "아이템끼리 다르게"가 아니라 "이력 분포와 같게"**다. 정확도만 최적화하면 다수 취향(액션)이 리스트를 독점하는 crowding-out을 막는 장치.
- ⚠ 프로덕션 배포 진술이 없다. 논문은 방법론 제안이고, Netflix 블로그·발표 어디에도 "calibration을 배포했다"는 문장을 찾지 못했다
[추정]— 검사 코퍼스는 netflixtechblog 전체 태그·research.netflix.com 출판 목록(2026-08-09 열람). "Netflix는 calibrated recommendations를 쓴다"고 쓰면 안 되고 "Netflix 연구자가 제안했다"까지가 안전하다. - 그래도 이 노트에 두는 이유: 감쇠·MMR·DPP·dedup 넷 다 "같음에 벌점" 계열인데 calibration만 분포 일치라는 다른 축이라, 다양성 레이어를 볼 때 "무엇을 목표로 하는 다양성인가"를 먼저 묻게 만든다.
중복 제거는 반대 방향일 수 있다. X는 dedup 필터 6종으로 같은 것을 지우는데, Netflix 홈은 같은 타이틀이 여러 행에 나오는 걸 허용하는 것으로 보인다 — 행마다 추천 이유(장르, BYW, Trending)가 다르고 아트워크 개인화(2017 전면 배포 [확인])까지 겹치면 같은 타이틀의 중복 노출이 "다른 설명의 재시도"로 기능한다 [추정] 행 간 중복 규칙의 1차 출처는 못 찾았고 직접 관찰도 아직 안 했다. 확인되면 "dedup은 위생"이라는 4번의 전제가 지면 구조에 따라 뒤집히는 사례가 된다.
지각된 다양성의 별도 레버 — 아트워크. 같은 타이틀이라도 회원마다 다른 이미지를 밴딧으로 고른다(2017 전면 배포, "we've rolled it out to everyone!" [확인] 블로그). 아이템 집합이 같아도 화면의 시각적 다양성이 달라진다 — X·Meta 문헌에는 대응물이 없는 레이어다.
상세는 → netflix.md
이 케이스에서 일반화할 수 있는 것
- 다양성은 랭킹 점수를 덮어쓴다. X는 2025 MMR과 2026 VMRanker 둘 다
score필드를 그대로 갈아친다. "랭커 점수"를 로그에서 볼 때 어느 단계 값인지 확인해야 한다. X 2026이weighted_score와score를 별도 필드로 남기는 이유가 이것이다[확인]ranking_scorer.rs:277-281. - 감쇠에는 floor를 둔다. 상한이 아니라 페널티로 만들어야 인기 작성자가 완전히 사라지지 않는다.
- 비싼 다양성(MMR/DPP)은 후보 풀 전체가 아니라 이미 좁혀진 리스트에 돈다. X 2025·2026 모두 선택 이후 단계로 배치돼 있다
[추정](2025는 훅이 벤더링된 코어에 없어 실행 위치 미확인). - 다양성은 리스트 앞이 아니라 꼬리에 건다. X 2025 MMR은 앞의
(1-diversityRatio)×n개에 상수를 더해 사실상 순수 relevance 순서를 보존하고, 그 뒤부터만 거리 보상을 준다. 상위 몇 개는 정확도, 아래는 다양성 — 이 구획이 명시적이다. - 다양성 레이어는 fail-open이다. 없어도 피드는 나간다. 그래서 조용히 죽어도 모른다. 감쇠는 인프로세스라 안 죽고, DPP는 원격이라 죽는다 — 이 비대칭이 왜 감쇠를 남겨두는지 설명한다
[추정]. - dedup 규칙은 좁게 잡는다. X는 "정확히 1개일 때만" 조건을 반복해서 쓴다. 과제거가 미제거보다 비싸다고 본 것
[추정]. - 공개하지 않는 것도 데이터다. Meta는 예측 헤드·후보 수·가중치를 정하는 방법까지 공개하면서 다양성·dedup만 일관되게 침묵한다.
[추정]다양성 규칙은 곧 "무엇을 덜 보여주는가"라서 정책 논쟁의 표적이 되기 쉽기 때문일 수 있다 — 근거는 2025년에 데모션 문서가 대폭 삭제된 패턴과 방향이 같다는 것뿐이다 → facebook.md. - 페널티가 곱셈이냐 덧셈이냐로 거부권 여부가 갈린다. 곱셈(IG 알림)은 유사하면 점수를 0으로 만들고, 덧셈(X MMR·카테고리)은 relevance가 이길 여지를 남긴다. 같은 "다양성 페널티"라는 이름이 정반대 강도를 가리킨다.
- 다양성 로직을 볼 때 비교 기준 집합을 먼저 물어야 한다. 슬레이트 내부(X MMR)냐, 과거 노출·발송 이력(IG 알림)이냐. 같은 max-similarity 수식이라도 이 선택으로 완전히 다른 물건이 된다.
- 다양성이 사후 재순위에만 있으란 법은 없다. Facebook은 "최근 1시간 같은 콘텐츠 타입 노출 횟수"를 랭킹 피처로 쓰고, Instagram은 retrieval DSL에 라운드로빈을 박는다. 사후 레이어만 찾으면 절반을 놓친다.
- 다양성의 단위는 지면 구조가 정한다. 단일 스트림(X·Meta)에서는 리스트 내 인접성이 문제라 감쇠·MMR이 답이고, 2차원 페이지(Netflix)에서는 행 구성이 문제라 다양성이 행 선택 알고리즘 안으로 들어간다. 같은 "다양성"이라는 말이 조작하는 대상이 다르다.
- "같음에 벌점"과 "분포 일치"는 다른 목표다. 감쇠·MMR·DPP는 인접한 같음을 벌하고, calibration은 리스트 전체의 장르 분포를 이력에 맞춘다. 전자는 최고 점수 취향이 리스트를 독점해도 아이템만 다르면 통과시키지만, 후자는 그 독점 자체(crowding-out)를 막는다.
- 수식 공개와 배포는 별개다. Netflix calibration은 RecSys 논문으로 수식 전체가 공개된 몇 안 되는 다양성 알고리즘인데 배포 진술이 없다. 반대로 Meta는 배포는 확실한데(pass 2) 수식이 없다. "공개 수준"과 "배포 확실성"은 독립 축이다.
누가 이걸 쓰는가
- X — 2025(MMR + 카테고리 페널티 + dedup 6종), 2026(작성자 감쇠 + DPP + dedup 3종). 네 방식이 전부 소스코드로 읽힌다. → x.md
[확인] - Facebook — pass 2 컨텍스트 패스에 content-type 다양성 규칙. 알고리즘 미공개, 구체 규칙은 "multiple video posts in a row" 한 줄뿐. 대신 같은 개념이 랭킹 피처로도 존재한다. → facebook.md
[확인] - Instagram — 피드는 "too many … in a row" 수준, retrieval에
diversify_by(round_robin), 알림에만 곱셈 페널티 수식 전체 공개. → instagram.md[확인] - Threads — 다양성·dedup 1차 출처 완전 부재. → threads.md
[관찰]2026-08-09 (ig-threads-feed 카드 본문 + Threads 엔지니어링 블로그 2편) - Netflix — 다양성이 행 선택 단계에(2015~), calibration 수식 공개(2018, 배포 미확인), 아트워크 개인화라는 별도 레버. dedup은 오히려 느슨할 가능성. → netflix.md
[확인] - 그 외 서비스 — 미조사. 열린 질문.
아직 확인 못한 것
- X 랭커 입력에 "최근 같은 콘텐츠 타입 노출 횟수" 계열 피처가 있는가. 없다고 쓰려면 repo-wide 확인이 필요하다. Facebook과의 대조가 여기 걸려 있다.
- Meta pass 2 다양성 규칙의 형태. 하드 슬롯 제약인지 점수 페널티인지조차 모른다 → facebook.md 열린 질문 2.
- Instagram 알림 프레임워크가 피드에도 적용되는가. 글이 알림 지면으로 한정해 서술한다.
- Threads에 다양성·dedup 레이어가 실재하는가. 부재가 "공개 안 함"인지 "없음"인지 판별 불가.
- Meta의 listwise 예측과 delivery frequency control의 형태. 존재 진술만 있고 기계적 서술이 없다.
- Netflix calibration의 배포 여부. 논문뿐, 배포 진술 없음.
- Netflix 행 간 중복 허용 규칙. 1차 출처도 직접 관찰도 아직 없다.
- GenPage(단일 트랜스포머 페이지 생성) 체제에서 다양성이 어디로 가는가. 행 선택이라는 명시적 다양성 지점이 사라지면 학습된 생성 분포에 암묵화된다 — 진술 없음 → netflix.md.
출처
공개 소스코드
- xai-org/x-algorithm — 2026, 공개 소스코드 (Apache 2.0).
home-mixer/scorers/,home-mixer/filters/,candidate-pipeline/. - twitter/the-algorithm — 2025-09-03 커밋
c54bec0, 공개 소스코드.home-mixer/.
Meta 블로그
- A New Ranking Framework for Better Notification Quality on Instagram — 2025, 블로그. Meta가 공개한 유일한 다양성 수식.
- How machine learning powers Facebook's News Feed ranking algorithm — 2021, 블로그. pass 2 = contextual pass.
- Designing a Constrained Exploration System — 2020, 블로그.
diversify_by(seed_id, method=round_robin). - The AI behind unconnected content recommendations — 2023, 블로그. pointwise and listwise, delivery frequency control.
- Instagram Ranking Explained — 2023-05-31, 블로그. "3연속" 디벙크의 1차 근거.
Meta Transparency Center (규제 대응 1차 문서)
- fb-feed · ig-feed · ig-threads-feed — AI system card. 다양성 서술과 그 부재의 근거.
Netflix
- The Netflix Recommender System (TMIS) — 2015, 논문. 행 선택의 관련성+다양성 최적화, 템플릿 폐지.
- Calibrated Recommendations (Steck, RecSys) — 2018, 논문. calibration 수식의 1차 출처. 배포 진술 없음.
- Artwork Personalization — 2017, 블로그. 전면 배포 진술.