DeepSeek V4+ Turbovec + RAG: Better OCR & Self-Hos -02
DeepSeek V4를 독특하게 만드는 것은 무엇입니까?
"DeepSeek-V4"의 가장 주목할만한 특징은 실용적인 비용으로 긴 텍스트 처리를 가능하게하는 건축 개선입니다.
Hugging Face 모델 카드는 V4가 Compressed Sparse Attention과 Heavily Compressed Attention을 결합한 하이브리드 주의 메커니즘을 사용한다고 설명합니다.
반면에 DeepSeek V4 공식 발표는 토큰별 압축 플러스 DeepSeek Sparse Attention이라는 표현을 사용합니다.
요컨대, 긴 컨텍스트를 다룰 때 계산 복잡성과 KV 캐시를 줄이고 약 백만 개의 토큰의 입력을보다 현실적인 비용으로 처리하는 것입니다.
모델 카드에 따르면 "DeepSeek-V4-Pro"는 1M 컨텍스트 구성의 "DeepSeek-V3.2"에 비해 단일 토큰 추론 중에 FLOP를 27 %, KV 캐시를 10 % 줄입니다.
지금까지 긴 컨텍스트를 처리하고 저렴하고 빠르게 작동 할 수있는 능력은 동시에 달성하기 어려웠습니다. 100만 개의 토큰을 읽을 수 있는 모델이 존재하더라도 비용, 대기 시간 및 메모리 소비는 실제 작동에서 문제가 됩니다. DeepSeek-V4는 이러한 문제를 직접 해결하는 모델이라고 할 수 있습니다.
Pro와 Flash의 차이점은 무엇입니까?
“ DeepSeek-V4-Pro ”는 시리즈의 플래그십 모델입니다. 글로벌 지식, 수학, STEM, 코딩 및 에이전트 기반 작업에서 고성능을 위해 설계되었으며 공식 벤치 마크에서 공개 모델 중에서 매우 높은 성능을 보여주었습니다.
“ DeepSeek-V4-Flash “는 가볍고 고속이며 저렴한 버전입니다. 총 284 바이트의 매개 변수와 13 바이트의 활성 매개 변수를 사용하면 Pro 버전보다 훨씬 작은 모델입니다. Pro보다 작음에도 불구하고 Flash는 추론 성능 측면에서 Pro에 가깝고 간단한 에이전트 작업에서 Pro와 유사하게 수행한다고 합니다.
코딩 시작합시다 : query.py
Ollama를 사용하여 bge-m3 임베딩 모델을 로드하여 텍스트를 벡터로 변환하기 시작했습니다. 그런 다음 저장된 TurboVec 인덱스를 index.tq에서 로드합니다.이 인덱스는 문서에서 이전에 만들었습니다.
쿼리가 들어오면 동일한 모델을 사용하여 벡터로 변환합니다.When a query comes in, I convert it into a vector using the same model. 이것은 모든 것을 동일한 벡터 공간에 유지합니다. 그런 다음 인덱스를 검색하여 키워드뿐만 아니라 의미에 따라 상위 3 개 가장 유사한 청크를 찾습니다.
다음으로, 나는 그 결과를 data.txt의 원래 줄에 다시 매핑하고, 정리하고, 중복을 제거하고, 주문을 유지합니다. 그런 다음 하나의 컨텍스트 문자열에 가입합니다.
마지막으로, 나는 엄격한 프롬프트와 함께 Ollama의 채팅을 사용하여 모델에이 컨텍스트를 보냈습니다. 나는 주어진 컨텍스트 만 사용하고 대답이 없으면 "상황에서 발견되지 않음"이라고 말하도록 강요합니다.
이것은 환각을 피하는 데 도움이됩니다. 최종 답변은 터미널에 인쇄됩니다.
from turbovec import TurboQuantIndex
from langchain_ollama import OllamaEmbeddings
from ollama import chat
embedder = OllamaEmbeddings(model="bge-m3:latest")
index = TurboQuantIndex.load("index.tq")
query = "What are the company’s total assets as of December 31, 2018?"
q_vec = [embedder.embed_query(query)]
scores, indices = index.search(q_vec, k=3)
with open("data.txt") as f:
texts = f.readlines()
retrieved = [texts[i].strip() for i in indices[0]]
retrieved = list(dict.fromkeys(retrieved))
context = "\n".join(retrieved)
print("\n🔍 Retrieved Context:\n")
for i, chunk in enumerate(retrieved, 1):
print(f"{i}. {chunk}")
response = chat(
model='deepseek-v4-flash:cloud',
messages=[
{
"role": "system",
"content": """You are a strict assistant.
Rules:
1. ONLY use the provided context.
2. DO NOT use prior knowledge.
3. If the answer is not fully in the context, say exactly: "Not found in context".
"""
},
{
"role": "user",
"content": f"Context:\n{context}\n\nQuestion: {query}\n\nAnswer:"
}
]
)
print("\n💡 Answer:\n")
print(response['message']['content'])
indexer.py
나는 Ollama를 사용하여 bge-m3 임베딩 모델을 설정하는 것으로 시작했습니다. 이 모델을 사용하여 텍스트를 벡터로 변환합니다.
다음으로, data/docs.txt 파일을 읽습니다. 추가 공간과 빈 줄을 제거하여 텍스트를 청소하므로 유용한 콘텐츠 만 유지합니다.
그런 다음 모든 텍스트 청크를 embed_documents로 전달합니다. 이것은 텍스트를 모델에 보내고 각 줄에 대해 하나의 벡터 인 벡터를 다시 제공합니다.
그 후, 나는 첫 번째를 사용하여 벡터의 크기를 감지합니다. 이를 바탕으로 4비트 양자화로 TurboVec 인덱스를 생성합니다.
벡터를 더 작게 만들고, 메모리를 저장하고, 많은 정확도를 잃지 않고 검색을 빠르게 유지하기 때문에 이것을 선택했습니다.
그런 다음 한 번에 인덱스에 모든 벡터를 추가합니다.
마지막으로 인덱스를 index/index.tq로 저장합니다. 이 파일은 쿼리를 실행할 때 나중에 로드하기 때문에 중요합니다. 그래서 저는 이 스크립트를 한 번만 실행하면 됩니다. 문서가 변경되지 않는 한 말입니다.
from turbovec import TurboQuantIndex
from langchain_ollama import OllamaEmbeddings
embedder = OllamaEmbeddings(model="bge-m3:latest")
with open("data/docs.txt") as f:
texts = [line.strip() for line in f.readlines() if line.strip()]
vectors = embedder.embed_documents(texts)
index = TurboQuantIndex(dim=len(vectors[0]), bit_width=4)
index.add(vectors)
index.write("index/index.tq")
print("✅ Index built successfully!")
rag.py
나는 Ollama를 사용하여 BGE-M3 임베딩 모델을 한 번로드하기 위해 스크립트를 설계했기 때문에 매번 다시로드되지 않습니다.
build_indexI에서 텍스트 청크를 가져와 embed_documents가 있는 벡터로 변환합니다.In build_indexI take text chunks and turn them into vectors with embed_documents. 그런 다음 TurboVec이 해당 형식을 요구하므로 NumPy float32 배열로 변환합니다. 벡터 크기를 자동으로 감지하고, 4비트 양자화로 인덱스를 만들고, 모든 벡터를 한 번에 추가합니다.
ask 함수에서 쿼리를 가져와 embed_query를 사용하여 벡터로 변환합니다. NumPy 배열로 싸서 상위 k 유사한 청크에 대한 인덱스를 검색합니다. 그런 다음 결과를 원본 텍스트로 다시 매핑하고 하나의 컨텍스트로 결합합니다.
마지막으로, Ollama의 채팅을 사용하여 모델에이 컨텍스트를 전송했습니다. 엄격한 프롬프트로, 그래서 주어진 데이터 만 사용합니다. 나는 대답과 회수 된 덩어리를 모두 반환합니다.
from turbovec import TurboQuantIndex
from langchain_ollama import OllamaEmbeddings
from ollama import chat
import numpy as np
embedder = OllamaEmbeddings(model="bge-m3:latest")
def build_index(texts):
vectors = embedder.embed_documents(texts)
vectors = np.array(vectors, dtype=np.float32) # add this
index = TurboQuantIndex(dim=vectors.shape[1], bit_width=4)
index.add(vectors)
return index
def ask(query, index, texts, k=3, model="deepseek-v4-flash"):
q_vec = np.array([embedder.embed_query(query)], dtype=np.float32)
scores, indices = index.search(q_vec, k=k)
retrieved = [texts[i] for i in indices[0]]
context = "\n".join(retrieved)
response = chat(
model=model,
messages=[
{
"role": "system",
"content": """STRICT MODE:
- Answer ONLY from context
- No external knowledge
- If missing: say 'Not found in context'
"""
},
{
"role": "user",
"content": f"Context:\n{context}\n\nQuestion: {query}"
}
]
)
return response['message']['content'], retrieved
Concsluion :
DeepSeek V4는 더 이상 수동적 대응자가 아닙니다. 복잡한 저장소를 자율적으로 이해하고, 자기 교정을하는 동안 수학적으로 도전적인 문제를 해결하고, 물리적 세계의 이미지에서 논리를 도출하는 활성 지능으로 진화합니다.
실리콘 밸리가 건설 한 "지능 장벽"은 DeepSeek이 발표 한 "알고리즘 적 우아함"에 의해 그 어느 때보 다 격렬하게 흔들리고 있습니다.
"DeepSeek-V4"는 단순한 모델 업데이트가 아닙니다. "긴 텍스트, 에이전트 기반, 저비용 및 개방형"솔루션의 시대를 향한 주요 전환점이 될 수 있습니다.
Turbovec은 누구나 즉시 사용할 수있는 빠른 벡터 인덱스로 Google의 혁신적인 TurboQuant 이론을 구현하는 우수한 오픈 소스 구현입니다.
데이터 독립성, 훈련 필요 없음, 극도의 압축 및 고속 검색의 네 가지 주요 기능을 자랑하며 지역 환경에서 전통적인 FAISS를 능가하는 성능을 제공합니다.