논문 링크

Q : 이 논문을 아주 자세하게 읽고 논문의 강점과 독창적인 지점을 설명해주고 핵심 알고리즘을 예시 입력을 들어서 전체적인 과정을 설명해줘 추가적으로 논문의 한계점에 대해서도 알려줘

논문 분석: SnapKV

이 논문은 **대형 언어 모델(LLM)**의 Key-Value(KV) 캐시 최적화를 목표로 한 새로운 알고리즘 SnapKV를 제안합니다. 아래는 논문의 핵심 기여, 알고리즘 동작 방식, 강점, 한계점 등을 한국어로 정리한 내용입니다.


논문의 강점

  1. 문제 해결
    LLM은 긴 프롬프트를 처리할 때 메모리 효율성지연 시간 문제가 발생합니다. 특히, 기존 방법들은 생성 중 발생하는 KV 캐시 크기만 압축했으나, SnapKV는 프롬프트 KV 캐시를 대상으로 하여 보다 근본적인 메모리 문제를 해결합니다.

  2. 독창적 접근

    • 모델의 주의(attention) 메커니즘에서, 실제 생성에 중요한 소수의 토큰만 높은 중요도를 가진다는 점을 관찰.
    • 이 패턴은 생성 전에 미리 식별 가능하며, 이를 활용해 불필요한 KV 데이터를 제거합니다.
  3. 성능 향상

    • 16K 토큰 길이에서 3.6배 빠른 디코딩 속도, 8.2배 향상된 메모리 효율성을 달성.
    • 최대 380K 토큰을 단일 GPU에서 처리 가능.
  4. 범용성
    SnapKV는 다양한 데이터셋(QMSum, Openreview, LongBench 등)에서 높은 성능을 보이며, HuggingFace 등의 프레임워크와도 쉽게 통합 가능합니다.

  5. 간결성과 실용성
    복잡한 추가 학습 없이 간단한 알고리즘으로 구현 가능하며, 코드 수정이 최소화됩니다.


SnapKV 알고리즘 설명

SnapKV는 긴 프롬프트의 KV 캐시를 압축하여 생성 과정에서 중요한 정보만 유지합니다. 아래는 SnapKV의 동작 과정을 예제와 함께 설명합니다.

예시 입력


단계별 과정

  1. 주의 가중치 계산

    • 관찰 윈도우와 나머지 프롬프트 간의 주의(attention) 가중치를 계산.
    • 예:
      • ["What"] = 0.1, ["is"] = 0.2, ["the"] = 0.1, ["population"] = 0.4, ["of"] = 0.2.
  2. 중요 토큰 선택 (Voting)

    • 주의 가중치가 높은 상위 토큰(k)을 선택.
    • 결과: ["population", "of"].
  3. 클러스터링

    • 선택된 토큰 주변의 인접 토큰까지 포함해 정보 손실을 최소화.
    • 최종 선택: ["the", "population", "of"].
  4. KV 캐시 압축

    • 선택된 토큰(["the", "population", "of"])과 관찰 윈도우(["of", "France?"])를 결합해 압축된 KV 캐시 생성.
    • 결과: ["the", "population", "of", "France?"].
  5. 생성 과정에서 활용

    • 압축된 KV 캐시를 사용해 프롬프트 길이를 줄이면서도 생성 성능 유지.

강점 요약

  1. 성능 보장:

    • SnapKV는 프롬프트에서 중요한 정보를 선별적으로 유지하면서도 정확도를 거의 잃지 않습니다.
  2. 다양한 데이터셋 적응:

    • QMSum, Openreview와 같은 다양한 유형의 데이터셋에서도 효과적.
  3. 긴 프롬프트 처리:

    • 최대 380K 토큰 길이를 처리 가능, 이는 기존의 모델 한계를 크게 확장.
  4. 효율적 자원 사용:

    • 메모리 사용량을 줄이고 디코딩 속도를 개선, 실제 GPU 리소스 부담 완화.

한계점

  1. 관찰 윈도우의 품질:

    • 관찰 윈도우 크기와 선택이 부적절할 경우 중요한 정보 손실이 발생할 가능성.
  2. 다양한 프롬프트:

    • 입력 형식이 지나치게 복잡하거나 노이즈가 많은 경우, 모델의 정확도가 감소할 수 있음.
  3. 압축률의 트레이드오프:

    • 지나치게 높은 압축률은 성능 저하를 초래할 가능성이 있음.
  4. 생성 중심 설계:

    • SnapKV는 생성 기반 작업에 초점이 맞춰져 있어, 분석이나 비생성 작업에는 직접적인 효과를 발휘하지 못할 수 있음.

결론

SnapKV는 긴 프롬프트 처리에 있어 LLM의 메모리 및 속도 효율성을 획기적으로 개선한 기술입니다. 단순하지만 효과적인 알고리즘으로 실제 애플리케이션에서 유용하며, 특히 긴 문맥을 요구하는 작업에 적합합니다. 다만, 관찰 윈도우 설정과 압축 비율의 조정이 성능에 중요한 영향을 미치므로 이를 고려해야 합니다.

Q : 논문의 핵심알고리즘을 예시를 들어 아주 자세하게 설명해주고 정리해 줘

SnapKV의 핵심 알고리즘 상세 설명

SnapKV는 프롬프트의 Key-Value(KV) 캐시를 압축하여 긴 문맥에서도 메모리 효율성생성 속도를 크게 향상시키는 알고리즘입니다. 아래는 SnapKV의 핵심 알고리즘을 단계별로 상세히 설명한 뒤, 예제를 통해 전체 과정을 시각화합니다.


알고리즘 개요

SnapKV는 프롬프트의 중요한 토큰을 식별하고 이를 중심으로 KV 캐시를 압축합니다. 이를 위해 다음과 같은 주요 개념과 과정이 포함됩니다.

  1. 프롬프트 분리:

    • 프롬프트를 **선행(prefix)**과 **관찰 윈도우(observation window)**로 나눔.
    • 관찰 윈도우는 프롬프트의 마지막 부분으로, 주의(attention) 패턴을 학습하는 데 사용됩니다.
  2. 중요 토큰 식별:

    • 관찰 윈도우의 주의 가중치(attention weights)를 계산하여 중요 토큰을 선택합니다.
    • 선택된 토큰은 생성에 필요한 핵심 정보를 유지합니다.
  3. 클러스터링 및 확장:

    • 주의 가중치가 높은 토큰 주변의 정보도 포함하여 정보 손실을 최소화합니다.
  4. KV 캐시 압축:

    • 선택된 중요한 토큰과 관찰 윈도우를 결합하여 압축된 KV 캐시를 생성합니다.

알고리즘의 수학적 표현

  1. 프롬프트 분리: [ L_{\text{prompt}} = L_{\text{prefix}} + L_{\text{obs}} ]

    • (L_{\text{prompt}}): 전체 프롬프트 길이
    • (L_{\text{prefix}}): 선행(prefix) 길이
    • (L_{\text{obs}}): 관찰 윈도우 길이
  2. 주의 가중치 계산: 관찰 윈도우에서 선행 부분의 주의 가중치를 계산합니다. [ C = \sum_{i=0}^{L_{\text{obs}}} W_{\text{obs}}[:, i, :] ]

    • (W_{\text{obs}}): 관찰 윈도우에서 계산된 주의 가중치.
  3. 중요 토큰 선택: (C)에서 상위 (k)개의 중요한 토큰을 선택합니다. [ I = \text{Top}k(C, k), \quad k = \lfloor p \cdot L{\text{prefix}} \rfloor ]

    • (p): 압축 비율(0 < (p) ≤ 1).
    • (I): 중요한 토큰의 인덱스.
  4. 클러스터링: 주변 정보를 포함하기 위해 가중치 (C)를 풀링(pooling)합니다.

  5. KV 캐시 압축: 선택된 토큰과 관찰 윈도우를 결합하여 새로운 KV 캐시 생성: [ \text{KV}_{\text{new}} = \text{Concat}(\text{Selected KV}, \text{Observation KV}) ]


SnapKV 알고리즘의 예시

입력


단계별 진행

  1. 프롬프트 분리:

    • 선행(prefix): ["What", "is", "the", "population"]
    • 관찰 윈도우(observation window): ["of", "France?"]
  2. 주의 가중치 계산:

    • 관찰 윈도우와 선행 간의 주의 가중치를 계산:
      PLAINTEXT
      "What" = 0.1, "is" = 0.2, "the" = 0.1, "population" = 0.4
      클릭하여 더 보기
    • 이때 “population"과 “is"가 상대적으로 중요한 토큰으로 평가됨.
  3. 중요 토큰 선택:

    • 압축 비율 (p = 50%): 상위 2개의 토큰을 선택.
    • 선택 결과: ["is", "population"]
  4. 클러스터링:

    • 선택된 토큰 주변 정보를 포함하여 클러스터링:
      최종 선택: ["the", "population", "of"]
  5. KV 캐시 압축:

    • 선택된 토큰과 관찰 윈도우를 결합:
      PLAINTEXT
      새로운 KV 캐시: ["the", "population", "of", "France?"]
      클릭하여 더 보기

결과 및 활용


정리

SnapKV는 다음을 통해 LLM의 성능을 최적화합니다:

  1. 효율성:
    불필요한 KV 데이터를 제거하여 메모리 사용량생성 지연 시간을 줄입니다.

  2. 정확성 유지:
    중요한 정보를 보존하며 압축하므로 생성 품질이 유지됩니다.

  3. 적용 가능성:
    다양한 데이터셋과 모델 구조에서 손쉽게 적용 가능.

  4. 간결함:
    복잡한 연산 없이 주의 가중치 기반으로 동작하여 직관적입니다.

SnapKV는 특히 긴 프롬프트를 처리해야 하는 문서 요약, 질의 응답 등에서 강력한 도구로 작용할 수 있습니다.

Q : 이 논문에서 제시한 결과를 자세하게 보고 다른 방법론에 비하여 특출난 점과 논문에서 제기하는 어떠한 방법이 이러한 결과를 도출하게 되었는지 논문에서 제시하는 이유와 너의 생각을 알려줘

논문에서 제시한 결과와 성과

SnapKV는 긴 문맥을 처리하는 LLM에서 성능, 메모리 효율, 처리 속도 면에서 탁월한 결과를 보여주었습니다. 논문에서는 여러 데이터셋과 테스트 환경에서 SnapKV의 성과를 다음과 같이 요약하고 있습니다:


결과 요약

  1. 성능 비교

    • 처리 속도:
      • 16K 토큰 입력 시 3.6배 더 빠른 디코딩 속도.
      • 380K 토큰 입력도 단일 GPU에서 처리 가능.
    • 메모리 효율:
      • 8.2배 향상된 메모리 효율.
    • 정확도 유지:
      • 대부분의 벤치마크에서 기존 방법과 유사한 정확도.
      • 일부 데이터셋에서는 SnapKV가 기존 방법을 능가.
  2. 주요 실험 결과

    • Needle-in-a-Haystack 테스트:
      • 최대 380K 토큰을 포함하는 프롬프트에서도 중요 정보를 성공적으로 복원.
      • 기존 모델은 33K 토큰에서 메모리 초과(OOM) 에러 발생.
    • LongBench 테스트:
      • Single-Document QA, Summarization, Few-Shot Learning 등 16개 벤치마크에서 기존 H2O 방식보다 높은 정확도를 달성.
      • SnapKV의 1024-토큰 압축은 H2O의 4096-토큰 방식보다 뛰어난 성과를 보여줌.
    • 디코딩 시간 비교:
      • SnapKV는 입력 길이와 상관없이 일정한 디코딩 속도를 유지.
      • 기존 방법론은 입력 길이가 길어질수록 디코딩 시간이 선형적으로 증가.

다른 방법론과 비교하여 SnapKV의 특출난 점

  1. Prompt KV Cache를 타겟으로 한 압축

    • 기존 방법론(H2O, StreamLLM 등)은 주로 생성 중에 추가되는 KV 캐시만 압축합니다.
    • SnapKV는 프롬프트에 초점을 맞추어, 더 큰 메모리 문제를 해결합니다.
    • 실제로 프롬프트는 생성되는 응답보다 훨씬 길기 때문에, 프롬프트 압축이 더 큰 성능 향상을 제공합니다.
  2. 사전 관찰 기반의 중요도 추출

    • SnapKV는 프롬프트 내 중요 토큰의 주의 패턴이 생성 전에 일정하다는 점을 발견했습니다.
    • 이를 기반으로 **관찰 윈도우(Observation Window)**를 활용하여 효율적인 캐시 압축을 수행합니다.
  3. 유연한 적용성

    • SnapKV는 추가 학습이나 모델 재구성이 필요하지 않으며, 기존 LLM 프레임워크에 쉽게 통합 가능합니다.
    • 이는 HuggingFace와 같은 대중적인 툴과도 호환되며, 실용적인 장점이 있습니다.

논문에서 제기하는 성공 요인

  1. 일관된 주의 패턴 관찰

    • SnapKV의 설계는 프롬프트 토큰 중 실제 생성 과정에서 중요하게 활용되는 패턴이 생성 전후로 크게 변하지 않는다는 발견에 기반합니다.
    • 이는 특정 토큰의 주의 가중치가 모델의 여러 층과 생성 단계에서 안정적으로 유지된다는 실험 결과(Fig. 2, Fig. 3)에 의해 뒷받침됩니다.
  2. 효율적인 투표 및 클러스터링

    • 관찰 윈도우를 통해 프롬프트에서 중요한 위치를 투표로 결정하고, 주변 토큰까지 포함하는 클러스터링(pooling) 기법을 사용합니다.
    • 이 과정은 중요한 정보를 유지하면서도 메모리 사용량을 대폭 줄이는 핵심 요소로 작용합니다.
  3. 압축된 KV 캐시 활용

    • SnapKV는 프롬프트 내 선택된 토큰과 관찰 윈도우를 결합하여 효율적이면서도 충분히 정보가 유지된 캐시를 생성합니다.
    • 이를 통해 입력 길이에 상관없이 일정한 디코딩 속도를 유지합니다.

나의 의견

SnapKV의 설계와 성과는 매우 실용적이며, 실제 환경에서의 사용 가능성이 높습니다. 특히 다음과 같은 점에서 큰 잠재력을 가진다고 생각합니다:

  1. 실용성 강조

    • 추가적인 모델 튜닝 없이 단순히 KV 캐시를 압축하는 방법으로, 긴 문맥 처리 문제를 크게 완화합니다.
    • 이는 실용적인 문제(예: 비용, GPU 메모리 제약)를 해결하는 데 적합합니다.
  2. 관찰 기반 접근의 강점

    • SnapKV의 성공은 데이터에서 발견한 패턴을 직관적으로 활용한 점에 있습니다.
    • 생성 과정 전후로 주의 패턴이 일정하다는 점은 단순하면서도 강력한 통찰이며, 이를 잘 활용했습니다.
  3. 확장 가능성

    • SnapKV는 긴 문맥 처리가 필요한 문서 요약, 질의응답, 코드 생성과 같은 분야에 특히 유용합니다.
    • 추가적으로, 메모리 압축이 필요한 비용 효율적인 AI 응용에서도 널리 활용될 가능성이 있습니다.

결론

SnapKV는 긴 문맥 처리를 위한 LLM의 효율성을 크게 개선한 중요한 기여입니다. 논문의 주요 성과는 관찰 윈도우 기반 접근법간단한 알고리즘 설계 덕분에 가능했으며, 이는 실용성과 효율성 모두를 만족시킵니다. 앞으로 SnapKV는 더욱 복잡한 작업(예: 다중 문서 처리, 고정밀 응용)에 활용 가능성을 확대할 여지가 있다고 봅니다.

Q : 이 논문의 입력데이터와 추론 과정에 대해서 예시를 들어 아주 자세하게 설명해 주겠니? 추가적으로 모델아키텍처의 구성 및 모델을 구성하는 연산과 메모리 요구량 컴퓨팅 요구량 대해서도 설명해줘

논문의 입력 데이터와 추론 과정

SnapKV는 LLM의 긴 프롬프트 입력을 효율적으로 처리하기 위한 KV 캐시 최적화 알고리즘입니다. 이 과정에서 입력 데이터는 프롬프트(질문, 대화, 문서 등)로 구성되며, 이를 통해 추론 과정을 상세히 설명하겠습니다.


입력 데이터

구성

  1. 프롬프트:

    • 사용자로부터 제공되는 긴 입력 데이터입니다. 예:
      PLAINTEXT
      "What is the population of France in 2023, and how has it changed since 2000?"
      클릭하여 더 보기
    • 길이: 16K ~ 380K 토큰 (긴 문맥 데이터).
  2. 관찰 윈도우:

    • 프롬프트의 마지막 부분 (예: 최근 대화 또는 문서 마지막 몇 줄).
    • SnapKV에서 중요한 정보를 추출하기 위해 사용됩니다.
    • 예:
      PLAINTEXT
      ["... how has it changed since 2000?"]
      클릭하여 더 보기

추론 과정 예시

단계별 상세 설명

  1. 프롬프트 분리:

    • SnapKV는 프롬프트를 두 부분으로 나눕니다:
      • 선행(prefix): 프롬프트의 첫 부분 (e.g., “What is the population of France”).
      • 관찰 윈도우(observation window): 마지막 부분 (e.g., “how has it changed since 2000?”).
    • 관찰 윈도우는 **프롬프트의 길이(Lobs)**로 정의되며, SnapKV는 이를 중심으로 중요 토큰을 식별합니다.
  2. 주의 가중치 계산:

    • 관찰 윈도우에서 선행 부분에 대한 주의(attention) 가중치를 계산합니다:
      PLAINTEXT
      Attention Weights (Wobs):
      "What" = 0.1, "is" = 0.2, "the" = 0.1, "population" = 0.4, "of" = 0.2
      클릭하여 더 보기
    • SnapKV는 주의 가중치가 높은 토큰을 중요 토큰으로 간주합니다.
  3. 중요 토큰 선택 및 클러스터링:

    • 주의 가중치가 높은 상위 (k)개의 토큰을 선택하고, 주변 토큰까지 클러스터링합니다:
      • 선택 결과: ["the", "population", "of"]
  4. KV 캐시 압축:

    • 선택된 중요한 토큰과 관찰 윈도우를 결합하여 새로운 KV 캐시 생성:
      PLAINTEXT
      새로운 KV 캐시 = ["the", "population", "of", "how has it changed since 2000?"]
      클릭하여 더 보기
  5. 생성 (디코딩):

    • 압축된 KV 캐시를 사용하여 답변 생성:
      PLAINTEXT
      "The population of France in 2023 is approximately 68 million, which represents a growth of 10% since 2000."
      클릭하여 더 보기

모델 아키텍처

SnapKV는 기존 Transformer 기반 LLM 아키텍처에 적용됩니다. SnapKV의 주요 구성 요소와 연산은 다음과 같습니다:

기본 Transformer 구조

  1. 입력 임베딩:

    • 텍스트 입력을 벡터로 변환 (토큰 임베딩 + 포지션 임베딩).
    • ( \text{입력 크기} = (L_{\text{prompt}} \times d_{\text{model}}) ).
  2. 주의 메커니즘 (Self-Attention):

    • ( \text{Query}(Q) = W_Q X, \quad \text{Key}(K) = W_K X, \quad \text{Value}(V) = W_V X )
    • Attention 연산: [ \text{Attention}(Q, K, V) = \text{Softmax} \left( \frac{QK^T}{\sqrt{d_k}} \right)V ]
    • SnapKV는 (Q, K, V) 연산 결과를 기반으로 중요한 토큰을 선택.
  3. KV 캐시 관리:

    • 각 Layer의 (K, V) 값을 저장.
    • SnapKV는 프롬프트에서 중요한 (K, V)를 선택해 캐시를 압축.
  4. Feedforward Layer:

    • ( X_{\text{output}} = W_2 \text{ReLU}(W_1 X + b_1) + b_2 )

메모리 및 연산 요구량

KV 캐시의 메모리 요구량

  1. 기본 KV 캐시 크기:

    • ( \text{메모리 크기} = (L_{\text{prompt}} \times d_{\text{model}} \times N_{\text{heads}}) )
    • 예: 16K 토큰, 1024 차원, 12 헤드 → 약 2.4GB 메모리 요구.
  2. SnapKV의 압축 효과:

    • (L_{\text{prompt}} \times p) 만큼 캐시 크기 축소.
    • 압축 비율 (p = 0.1)일 때 메모리 사용량은 기존 대비 90% 감소.

계산량

  1. 기본 Attention 계산량:

    • ( O(L_{\text{prompt}}^2 \cdot d_{\text{model}}) ).
    • 긴 입력에서는 선형적으로 증가하여 비효율적.
  2. SnapKV의 효율성:

    • SnapKV는 중요 토큰만 선택하므로 계산량이 (O(L_{\text{compressed}}^2 \cdot d_{\text{model}}))로 줄어듦.
    • (p = 0.1)이라면 계산량은 기존 대비 약 1/100 수준.

SnapKV의 설계가 결과를 도출한 이유

  1. 효율적인 메모리 사용:

    • SnapKV는 긴 프롬프트에서 중요하지 않은 데이터를 제거하여 메모리 초과 문제를 해결.
  2. 주의 패턴의 일관성 활용:

    • 관찰 윈도우에서 중요한 토큰을 미리 식별하여 연산량과 메모리를 최적화.
  3. 클러스터링으로 정보 손실 최소화:

    • 주요 토큰뿐만 아니라 주변 정보까지 포함해 정보 누락을 방지.
  4. 모델 구조와의 간단한 통합:

    • SnapKV는 기존 Transformer의 KV 캐시 관리 구조를 그대로 활용하여 효율적으로 작동.

결론

SnapKV는 입력 데이터를 효율적으로 처리하며, 긴 문맥을 요구하는 작업에서도 메모리 사용량과 연산량을 대폭 줄입니다. 이를 통해 기존 Transformer 기반 모델의 성능 한계를 뛰어넘는 결과를 도출했습니다. SnapKV의 설계는 메모리 효율성, 계산량 최적화, 정확성 유지를 모두 달성하는데 중요한 역할을 했습니다.

Q : 이 논문의 한계를 극복하기 위한 방법으로 어떤 연구흐름이 있는지 정리해서 자세하게 설명해 줘

SnapKV 논문에서 제시된 한계를 극복하기 위해 발전할 수 있는 연구 흐름은 크게 다음과 같이 나뉩니다:


1. 관찰 윈도우(Observation Window)의 최적화

SnapKV의 주요 메커니즘은 관찰 윈도우를 기반으로 프롬프트 내 중요한 정보를 식별하는 것입니다. 하지만 관찰 윈도우의 선택이 부적절하면 중요한 정보가 누락될 가능성이 있습니다.

제안되는 연구 방향


2. 중요 토큰 선택의 정밀도 개선

SnapKV는 주의 가중치 기반으로 중요한 토큰을 선택하지만, 단순한 가중치 비교는 일부 복잡한 문맥에서 정확도가 떨어질 수 있습니다.

제안되는 연구 방향


3. 압축된 KV 캐시의 정보 손실 최소화

압축된 KV 캐시가 중요한 정보를 놓칠 경우 생성된 결과가 부정확해질 수 있습니다. 이는 SnapKV의 압축 비율에 따라 가중될 수 있는 문제입니다.

제안되는 연구 방향


4. 긴 문맥 처리의 확장성

SnapKV는 긴 문맥을 처리할 수 있지만, 1M 이상의 토큰을 다루는 경우에는 한계가 있을 수 있습니다.

제안되는 연구 방향


5. 추론 속도 최적화

SnapKV는 디코딩 속도를 크게 향상시켰지만, 대규모 모델에서는 여전히 실시간 응답이 어려운 경우가 있습니다.

제안되는 연구 방향


6. 비생성 작업으로의 확장

SnapKV는 주로 생성 기반 작업(질의응답, 요약)에 초점을 맞추고 있습니다. 비생성 작업에서도 활용할 수 있도록 연구를 확장할 필요가 있습니다.

제안되는 연구 방향


결론

SnapKV는 긴 문맥 처리에서 메모리와 속도 면에서 혁신적인 기여를 했지만, 관찰 윈도우의 최적화, 정보 손실 최소화, 더욱 긴 문맥 처리 등의 한계를 극복해야 합니다. 이러한 연구 방향은 적응형 압축, 계층적 처리, 병렬화 등을 통해 SnapKV의 효과를 확장하고, 생성 및 비생성 작업에 걸쳐 그 응용 가능성을 넓힐 수 있습니다.

라이선스

저작자: Jaehun Ryu

링크: https://jaehun.me/posts/snapkv-llm-knows-what-you-are-looking-for-before-generation/

라이선스: CC BY 4.0

이 저작물은 크리에이티브 커먼즈 저작자표시 4.0 국제 라이선스에 따라 이용할 수 있습니다. 출처를 밝히면 상업적 목적을 포함해 자유롭게 이용 가능합니다.

댓글

검색 시작

검색어를 입력하세요

↑↓
ESC
⌘K 단축키