F16~F20에서 F21~F25로 — 서열에서 세포로
F16부터 F20까지는 DNA 서열 자체를 언어로 다뤘습니다. 그런데 S26~S38(단일세포 시리즈)에서 이미 확인했듯, 실무에서 자주 마주치는 데이터는 서열이 아니라 세포 하나당 수천~수만 개 유전자의 발현량 벡터입니다. 이 벡터를 언어모델의 입력으로 재구성할 수 있을까요? scGPT(2024, Wang lab)는 이 질문에 "그렇다"고 답한 대표적인 단일세포 파운데이션 모델입니다.
원리 — 발현 벡터를 시퀀스로 재구성하기
유전자 발현은 원래 시퀀스가 아니다
S27~S31에서 다룬 정규화·HVG 선택 이후, 세포 하나는 (선택된) 유전자 수만큼의 차원을 가진 발현량 벡터로 표현됩니다. 이 벡터는 순서가 없는 집합에 가깝습니다 — 어떤 유전자가 몇 번째 차원에 오는지는 데이터 처리 파이프라인이 정하는 임의적 선택일 뿐, 생물학적 의미가 있는 "순서"가 아닙니다.
scGPT는 유전자 ID와 각 유전자의 발현값을 함께 입력으로 표현합니다. 구현에서 유전자 목록의 순서는 텐서를 구성하기 위한 규약일 뿐, 자연어처럼 생물학적 "단어 순서"를 뜻하지는 않습니다. 따라서 실제 추론·미세조정에서는 공식 어휘와 전처리기를 사용해 유전자 ID와 값의 정렬을 일관되게 맞춰야 합니다.
값 이산화(value binning)와 이중 임베딩
발현량은 자연어의 이산 토큰과 달리 연속적인 값입니다. scGPT는 이를 몇 개의 구간(bin)으로 이산화한 뒤, 각 토큰을 유전자 정체성 임베딩과 발현량 구간 임베딩 두 가지의 조합으로 표현합니다.
이렇게 하면 "어떤 유전자인가"와 "얼마나 발현되었는가"라는 서로 다른 두 정보를 하나의 트랜스포머 입력 안에 함께 인코딩할 수 있습니다.
사전학습 — masked gene prediction
사전학습 목표는 F16의 masked k-mer prediction과 발상이 같습니다. 세포 안의 일부 유전자 토큰을 가리고, 나머지 유전자들의 발현 패턴만으로 가려진 유전자의 발현 구간을 예측하도록 학습합니다.
수백만 개 세포에 걸쳐 이 목표로 사전학습하면, 모델은 "이 유전자들이 함께 발현될 때 저 유전자도 대개 이런 수준으로 발현된다"는 유전자 공발현(co-expression) 통계 구조를 자연스럽게 학습하게 됩니다.
손 계산 예제: 발현 구간 이산화
연속 발현값 를 5개 구간으로 이산화한다고 합시다. 로그 정규화된 발현값의 범위가 대략 이라면 구간 폭은
발현값 인 유전자는
에 배정됩니다. 구간 수를 늘리면 발현량 정보의 해상도가 높아지지만 어휘 크기와 학습 난이도도 함께 늘어나므로, 이 값은 실전에서 검증을 거쳐 튜닝해야 합니다.
실습: Scanpy 전처리 후 scGPT류 임베딩 추출 흐름 재현
# Colab T4, 무료 티어. S26~S31의 Scanpy 전처리 파이프라인을 그대로 이어받습니다.
import scanpy as sc
# 1. S27~S31에서 다룬 표준 전처리를 먼저 적용합니다 (QC, 정규화, HVG 선택).adata = sc.read_h5ad("pbmc3k_processed.h5ad") # S26~S31 결과물 재활용 가정
# 2. 발현 상위 유전자를 살펴보기 위한 개념 코드입니다.# 이것은 공식 scGPT 입력을 재현하지 않습니다. 실제 모델에는 공식 어휘와# 전처리기를 사용해 (gene ID, expression value) 텐서를 구성하세요.def cell_to_gene_sequence(expr_row, gene_names, n_bins: int = 5, top_k: int = 200): """ 한 세포의 발현 벡터에서 발현량 상위 top_k개 유전자를 골라 탐색용 (유전자ID, 발현구간) 목록을 만듭니다. """ import numpy as np nonzero_idx = expr_row.nonzero()[0] sorted_idx = nonzero_idx[expr_row[nonzero_idx].argsort()[::-1][:top_k]] max_val = expr_row.max() if expr_row.max() > 0 else 1.0 bins = np.floor(expr_row[sorted_idx] / max_val * (n_bins - 1)).astype(int) return list(zip(gene_names[sorted_idx], bins))
# 실제 사전학습 가중치를 불러와 임베딩을 뽑으려면 공식 저장소의 체크포인트와# 전처리 스크립트를 그대로 따르는 것이 안전합니다 (scGPT 공식 GitHub).이렇게 얻은 세포 임베딩은 F17의 Nucleotide Transformer 임베딩과 마찬가지로, 세포 유형 주석(cell type annotation), 배치 보정(F22~F23에서 다룰 통합 문제와 연결), 또는 소량 레이블로 미세조정하는 다운스트림 과제에 재사용할 수 있습니다.
CS 매핑
- 비순서 데이터의 시퀀스화: 원래 순서가 없는 집합 데이터를 인위적 순서(발현량 순 등)로 정렬해 시퀀스 모델에 입력하는 방식은, 그래프나 집합 데이터를 다루는 딥러닝에서 흔히 쓰는 직렬화(serialization) 전략과 같은 발상입니다.
- 이산화와 임베딩 결합: 연속값을 구간으로 나누고 이를 범주형 임베딩으로 다루는 방식은 자연어 처리의 위치 임베딩(positional embedding)과 토큰 임베딩을 더하는 방식과 구조적으로 동일합니다.
- F16과의 평행 구조: masked k-mer prediction(F16)과 masked gene prediction(scGPT)은 도메인만 다를 뿐 자기지도학습의 동일한 설계 패턴을 공유합니다.
자주 만나는 결함
- 탐색용 top_k 목록을 공식 scGPT 입력으로 오해: 위 예제의 상위 유전자 목록은 설명을 위한 축약입니다. 모델별 공식 어휘·유전자 필터·값 전처리를 따르지 않으면 사전학습 가중치와 호환되지 않을 수 있습니다.
- 사전학습 임베딩을 배치 보정 없이 바로 통합에 사용: scGPT 임베딩도 기술적 배치 효과에서 완전히 자유롭지 않습니다. S32~S33에서 다룬 Harmony·scVI 같은 배치 보정 절차와 병행 검증이 필요합니다.
더 깊게 파고 싶다면
본문은 BPD 연구진이 직접 재구성한 서술입니다. 원 논문과 공식 자료로 심화해봅시다.
- scGPT 원 논문: Cui et al. (2024), scGPT: toward building a foundation model for single-cell multi-omics using generative AI, Nature Methods 21.
- 단일세포 전처리 배경: S26~S31 (
scrna-seq-intro-and-data-structure이후 시리즈).
다음 편(F22)에서는 Geneformer가 발현값을 아예 쓰지 않고 순위 정보만으로 유전자 문맥을 학습하는, 또 다른 설계 선택을 살펴봅니다.