Я запускаю конвейер RAG с помощью Haystack (haystack-ai==2.6.0), а также ВЧ-модель и библиотеку трансформаторов (transformers==4.39.3).
Вот как выглядит мой код:
tokenizer = AutoTokenizer.from_pretrained(pretrained_model_name_or_path=mymodel, cache_dir=cache_dir)
if tokenizer.pad_token is None:
# tokenizer.add_special_tokens({'pad_token': tokenizer.eos_token})
# tokenizer.add_special_tokens({'pad_token': '[PAD]'})
tokenizer.pad_token = tokenizer.eos_token
embedder = SentenceTransformersDocumentEmbedder(model=mymodel)
text_embedder = SentenceTransformersTextEmbedder(model=mymodel)
generator = HuggingFaceLocalGenerator(model=mymodel)
rag_pipeline = Pipeline()
rag_pipeline.add_component("converter", MarkdownToDocument())
rag_pipeline.add_component("splitter", DocumentSplitter(split_by="sentence", split_length=2))
rag_pipeline.add_component("embedder", embedder)
rag_pipeline.add_component("text_embedder", text_embedder)
rag_pipeline.add_component("retriever", MilvusEmbeddingRetriever(document_store=document_store, top_k=3))
rag_pipeline.add_component("writer", DocumentWriter(document_store))
rag_pipeline.add_component("prompt_builder", PromptBuilder(template=prompt_template))
rag_pipeline.add_component("generator", generator)
rag_pipeline.connect("converter.documents", "splitter.documents")
rag_pipeline.connect("splitter.documents", "embedder.documents")
rag_pipeline.connect("embedder", "writer")
rag_pipeline.connect("text_embedder.embedding", "retriever.query_embedding")
rag_pipeline.connect("retriever.documents", "prompt_builder.documents")
rag_pipeline.connect("prompt_builder", "generator")
results = rag_pipeline.run({
"converter": {"sources": [file_path]},
"text_embedder": {"text": question},
"prompt_builder": {"query": question},
})
print("RAG answer:", results["generator"]["replies"][0])
При запуске метода rag_pipeline.run() я получаю следующую ошибку относительно токенизатора и встроенного устройства:
ValueError: Asking to pad but the tokenizer does not have a padding token. Please select a token to use as `pad_token` `(tokenizer.pad_token = tokenizer.eos_token e.g.)` or add a new pad token via `tokenizer.add_special_tokens({'pad_token': '[PAD]'})`.
Я уже видел несколько вопросов и страниц, посвященных подобной проблеме, но мне все еще не удалось отладить проблему в этом конвейере RAG (например, этот вопрос о stackoverflow или эту проблему с GitHub).
/>
Обратите внимание, что в начале кода я закомментировал разные версии, в которых пытался создать токен площадки:
if tokenizer.pad_token is None:
# tokenizer.add_special_tokens({'pad_token': tokenizer.eos_token})
# tokenizer.add_special_tokens({'pad_token': '[PAD]'})
tokenizer.pad_token = tokenizer.eos_token
Но все они приводят к одинаковой ошибке. Любая помощь будет оценена по достоинству.
РЕДАКТИРОВАТЬ 1:
mymodel = "occiglot/occiglot-7b-eu5" (https://huggingface.co/occiglot/occiglot-7b-eu5)
Я импортирую средства для внедрения из haystack, а не из преобразователей предложений:
from haystack.components.embedders import SentenceTransformersTextEmbedder
from haystack.components.embedders import SentenceTransformersDocumentEmbedder
А также попробовал использовать специальные оболочки для средств внедрения, чтобы убедиться, что они используют токенизатор, но все равно получаю ту же ошибку:
# Custom Wrapper for Document Embedder
class CustomDocumentEmbedder(SentenceTransformersDocumentEmbedder):
def __init__(self, model_name, cache_dir=None):
self.tokenizer = AutoTokenizer.from_pretrained(model_name, cache_dir=cache_dir)
# Ensure pad_token is set correctly
if self.tokenizer.pad_token is None:
self.tokenizer.add_special_tokens({'pad_token': self.tokenizer.eos_token})
super().__init__(model=model_name)
# Override the embed method to force the tokenizer with padding
def embed(self, documents):
inputs = self.tokenizer([doc.content for doc in documents], padding=True, truncation=True, return_tensors="pt")
embeddings = self.model.encode(inputs["input_ids"])
return embeddings
# Custom Wrapper for Text Embedder
class CustomTextEmbedder(SentenceTransformersTextEmbedder):
def __init__(self, model_name, cache_dir=None):
self.tokenizer = AutoTokenizer.from_pretrained(model_name, cache_dir=cache_dir)
# Ensure pad_token is set correctly
if self.tokenizer.pad_token is None:
self.tokenizer.add_special_tokens({'pad_token': self.tokenizer.eos_token})
super().__init__(model=model_name)
# Override the embed method to force the tokenizer with padding
def embed(self, text):
inputs = self.tokenizer(text, padding=True, truncation=True, return_tensors="pt")
embeddings = self.model.encode(inputs["input_ids"])
return embeddings
# Custom Wrapper for HuggingFace Generator
class CustomGenerator(HuggingFaceLocalGenerator):
def __init__(self, model_name, cache_dir=None):
self.tokenizer = AutoTokenizer.from_pretrained(model_name, cache_dir=cache_dir)
# Ensure pad_token is set correctly
if self.tokenizer.pad_token is None:
self.tokenizer.add_special_tokens({'pad_token': self.tokenizer.eos_token})
super().__init__(model=model_name)
# Override generate method to ensure tokenizer is used correctly
def generate(self, query, **kwargs):
inputs = self.tokenizer(query, padding=True, truncation=True, return_tensors="pt")
output = self.model.generate(inputs["input_ids"], **kwargs)
generated_text = self.tokenizer.decode(output[0], skip_special_tokens=True)
return generated_text
embedder = CustomDocumentEmbedder(model_name=mymodel)
text_embedder = CustomTextEmbedder(model_name=mymodel)
generator = CustomGenerator(model_name=mymodel)
Подробнее здесь: https://stackoverflow.com/questions/790 ... ve-a-paddi