LLM에 이미 포함된 '무료' 멀티모달 임베딩 모델: vLLM 플러그인 + 상위 PR
요약
본 글은 vLLM을 사용하는 LLM에서 별도의 임베딩 모델 없이도 텍스트 및 이미지 유사도 임베딩을 얻는 방법을 소개합니다. 이는 LLM의 내부 은닉 상태 벡터를 활용하여 구현되며, RAG나 시맨틱 검색 등 다양한 애플리케이션에 적용할 수 있습니다.
핵심 포인트
- vLLM 플러그인을 통해 LLM에서 직접 임베딩 추출 가능
- 내부 은닉 상태(Hidden State) 벡터를 임베딩으로 사용
- RAG, 시맨틱 검색, 클러스터링 등 다양한 분야 활용에 유용
- llama.cpp 포팅 및 vLLM 통합을 위한 피드백 요청
면책 조항: 저는 이 플러그인을 만든 NuMind의 직원입니다. 요약하자면: 이미 로드된 LLM으로부터 텍스트/이미지(유사도) 임베딩을 얻을 수 있습니다 :-) vLLM에 의해 이미 서비스되고 있는 LLM으로부터 임베딩을 더 쉽게 얻는 방법을 개발해 왔습니다. 아이디어는 간단합니다 (그리고 저의 것이 아닌데 논의할 것입니다): 모델은 프롬프트의 내부 표현(디코더 레이어당 1개의 은닉 상태)을 계산하여 첫 번째 출력 토큰을 예측합니다. 우리는 채팅 API를 통해 마지막 은닉 상태 벡터를 노출합니다 (표준은 아니지만 openai-api 및 openai 클라이언트와 호환됨). 이와 관련하여 몇 가지 흥미로운 논문들이 있습니다: PromptEOL, PromptReps, 그리고 E5-V. E5-V 작업에 대해 간략하게 요약하자면 (제가 가장 많은 작업을 기반으로 한 논문): 그들은 '다음 단어로 프롬프트 요약하기'를 사용하고 마지막 은닉 상태(마지막 디코더 블록의 은닉 상태)를 임베딩으로 사용합니다. 그리고 이것은 상당히 잘 작동합니다. 직관적으로, 하나의 토큰/단어 요약을 요청하는 것이 모델이 해당 위치에 관련 정보를 집중하도록 장려한다는 것입니다. NuMind에서는 구조화된 데이터를 추출하고 이미지/문서를 Markdown으로 변환하기 위해 Apache-2.0 하의 오픈 웨이트 4B 모델인 NuExtract3를 구축합니다. 또한 문서 추출을 더 큰 (프로) 모델로 사용할 수 있는 NuExtract 플랫폼과 API도 보유하고 있습니다. (더 자세한 정보는 제 NuExtract 3 발표 게시물을 참조하십시오). 저희 모델이 주로 json을 출력하기 때문에(Markdown 모드 제외), 사용되는 프롬프트는 {"short description": "string"}입니다. 이 플러그인은 로컬 RAG, 시맨틱 검색, 문서 또는 이미지 클러스터링, 또는 벡터 위에 작은 분류기를 훈련하는 데 유용할 수 있습니다. 물론, 은닉 상태가 자동으로 좋은 임베딩인 것은 아닙니다. 품질은 모델, 프롬프트 및 작업에 따라 달라지며, 전용 임베딩 모델이 더 빠르거나 좋을 수 있습니다.
이 플러그인은 이러한 실험을 더 쉽게(그리고 이전에 사용했던 수동 PyTorch + transformers 설정보다 빠르게) 수행할 수 있게 해줍니다. 저는 이것이 vLLM에 통합되기를 정말 바랍니다: PR #57185. 제 코드에 대한 검토나 의견이 있거나, 이것을 병합하는 데 도움을 받을 수 있는 사람을 아신다면 정말 좋을 것 같습니다. 약간의 엣지 케이스라는 것을 알지만 여전히 유용하다고 생각합니다. 그동안 vLLM용 Apache-2.0 플러그인이 있습니다. 토큰 하나짜리 비스트리밍 채팅 요청에서 옵트인하면 응답으로 벡터를 얻을 수 있습니다. 일반적인 채팅과 스트리밍은 동일한 서버에서 계속 작동합니다. README에 예제와 현재 지원/유효성 한계가 나와 있습니다. 이 워크플로우를 llama.cpp로 포팅하는 것에 관심이 있을까요? 여기 대부분의 사람들은 vLLM보다 llama.cpp를 사용하므로, 저도 거기에 PR을 올리려고 시도할 수 있습니다. vLLM에 코드를 받아들이는 것이 더 쉬운지 아니면 llama.cpp에 받는 것이 더 쉬운지는 모르겠습니다. 피드백이 있다면 공유해 주세요 :-) 면책 조항: 저는 이 플러그인의 개발사인 NuMind에서 근무합니다. 요약: 이미 로드된 LLM으로부터 텍스트/이미지(유사도) 임베딩을 얻는 것만 하면 됩니다 :-) 저는 vLLM에 의해 이미 서비스되고 있는 LLM(가급적 멀티모달)으로부터 임베딩을 더 쉽게 얻는 방법을 개발해 왔습니다. 아이디어는 간단합니다 (그리고 저의 아이디어는 아닙니다): 모델은 프롬프트의 첫 번째 출력 토큰을 예측하기 위해 내부 표현(디코더 레이어당 1개의 은닉 상태)을 이미 계산하고 있습니다. 저희는 채팅 API를 통해 마지막 은닉 상태 벡터를 노출합니다 (이는 표준은 아니지만 openai-api 및 openai 클라이언트와 호환됩니다). 이에 관한 흥미로운 논문들이 몇 가지 있습니다: PromptEOL, PromptReps, 그리고 E5-V. E5-V 작업에 대해 간략히 요약하자면 (제가 가장 많은 작업을 기반으로 한 논문): 그들은 '위 이미지의 프롬프트'를 사용하여 이 방식으로 임베딩을 얻고 마지막 은닉 상태(마지막 디코더 블록의 은닉 상태)를 임베딩으로 사용합니다. 이는 상당히 잘 작동합니다.
직관적으로 볼 때, 하나의 토큰 또는 단어 요약을 요청하는 것은 모델이 관련 정보를 해당 위치에 집중하도록 장려합니다. NuMind에서는 구조화된 데이터를 추출하고 이미지/문서를 Markdown으로 변환하기 위해 Apache-2.0 기반의 오픈 웨이트 4B 모델인 NuExtract3를 구축했습니다. 또한, 훨씬 더 큰 (프로) 모델을 사용하여 문서 추출을 할 수 있는 NuExtract 플랫폼과 API도 보유하고 있습니다. (더 자세한 정보는 제 NuExtract 3 발표 게시물을 참조하세요). 저희 모델이 주로 JSON을 출력하기 때문에(Markdown 모드를 제외하고), 사용되는 프롬프트는 {"short description": "string"}입니다. 이 플러그인은 로컬 RAG, 시맨틱 검색, 문서 또는 이미지 클러스터링, 또는 벡터 위에 작은 분류기 훈련에 유용할 수 있습니다. 품질은 모델, 프롬프트, 작업에 따라 달라지며, 전용 임베딩 모델이 더 빠르거나 좋을 수도 있습니다. 이 플러그인은 이러한 실험을 훨씬 쉽게 만듭니다 (그리고 우리가 이를 실행 가능한 임베딩으로 판단하기 위해 사용했던 수동 PyTorch + transformers 설정보다도 빠릅니다). 저는 이것이 vLLM에 병합되기를 정말 바랍니다: PR #57185. 제 코드에 대한 검토/의견이나, 이것을 병합할 수 있도록 제가 이야기 나눌 만한 사람을 아신다면 정말 좋을 것 같습니다. 일종의 엣지 케이스라는 것을 알지만 여전히 유용하다고 생각합니다. 그동안 저희는 vLLM용 Apache-2.0 플러그인을 가지고 있습니다. 추가해야 할 인수가 하나 있는데, max_tokens=1이며 임베딩은 추가 응답 인수에 포함될 것입니다. 일반 채팅 및 스트리밍은 동일한 서버에서 여전히 작동합니다. README에 예시와 현재 지원/유효성 한계가 나와 있습니다. 제가 이 워크플로우를 llama.cpp로 포팅하는 것에 관심이 있으신가요? 이곳의 대부분의 사람들이 사용하는 것이 그것이라는 것을 알기 때문에, 저도 거기에 PR을 제출해 볼 수 있을 것 같습니다. vLLM에 코드를 받아들이는 것이 더 쉬운지 아니면 llama.cpp에 하는 것이 더 쉬운지는 모르겠습니다 (vLLM에는 꽤 길어 보입니다). 피드백이 있으시면 공유해 주십시오 :-) /u/Gailenstorm 제출 [링크] [댓글]
AI 자동 생성 콘텐츠
본 콘텐츠는 Reddit AI Engineering의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기