Repository: deepset-ai/haystack

Issue:
`DensePassageRetriever` not working with non-bert models
**Describe the bug**
Previously, `DensePassageRetriever` was working with any transformer models, but it seems that no it works only with BERT models.

**Error message**
```
Traceback (most recent call last):
  File "/opt/homebrew/Caskroom/miniforge/base/envs/haystack/lib/python3.10/site-packages/IPython/core/interactiveshell.py", line 3505, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-5-205c91daa59a>", line 1, in <module>
    dpr.embed_queries(queries=["Sample query."])
  File "/Users/bogdan/Repositories/haystack/haystack/nodes/retriever/dense.py", line 548, in embed_queries
    result = self._get_predictions(query_dicts)["query"]
  File "/Users/bogdan/Repositories/haystack/haystack/nodes/retriever/dense.py", line 519, in _get_predictions
    query_embeddings, passage_embeddings = self.model.forward(
  File "/Users/bogdan/Repositories/haystack/haystack/modeling/model/biadaptive_model.py", line 290, in forward
    pooled_output = self.forward_lm(
  File "/Users/bogdan/Repositories/haystack/haystack/modeling/model/biadaptive_model.py", line 350, in forward_lm
    pooled_output1, _ = self.language_model1(
  File "/opt/homebrew/Caskroom/miniforge/base/envs/haystack/lib/python3.10/site-packages/torch/nn/modules/module.py", line 1501, in _call_impl
    return forward_call(*args, **kwargs)
  File "/Users/bogdan/Repositories/haystack/haystack/modeling/model/language_model.py", line 719, in forward
    model_output = self.model(
  File "/opt/homebrew/Caskroom/miniforge/base/envs/haystack/lib/python3.10/site-packages/torch/nn/modules/module.py", line 1501, in _call_impl
    return forward_call(*args, **kwargs)
  File "/opt/homebrew/Caskroom/miniforge/base/envs/haystack/lib/python3.10/site-packages/transformers/models/dpr/modeling_dpr.py", line 587, in forward
    outputs = self.question_encoder(
  File "/opt/homebrew/Caskroom/miniforge/base/envs/haystack/lib/python3.10/site-packages/torch/nn/modules/module.py", line 1501, in _call_impl
    return forward_call(*args, **kwargs)
  File "/opt/homebrew/Caskroom/miniforge/base/envs/haystack/lib/python3.10/site-packages/transformers/models/dpr/modeling_dpr.py", line 196, in forward
    outputs = self.bert_model(
  File "/opt/homebrew/Caskroom/miniforge/base/envs/haystack/lib/python3.10/site-packages/torch/nn/modules/module.py", line 1501, in _call_impl
    return forward_call(*args, **kwargs)
  File "/opt/homebrew/Caskroom/miniforge/base/envs/haystack/lib/python3.10/site-packages/transformers/models/camembert/modeling_camembert.py", line 897, in forward
    embedding_output = self.embeddings(
  File "/opt/homebrew/Caskroom/miniforge/base/envs/haystack/lib/python3.10/site-packages/torch/nn/modules/module.py", line 1501, in _call_impl
    return forward_call(*args, **kwargs)
  File "/opt/homebrew/Caskroom/miniforge/base/envs/haystack/lib/python3.10/site-packages/transformers/models/camembert/modeling_camembert.py", line 137, in forward
    inputs_embeds = self.word_embeddings(input_ids)
  File "/opt/homebrew/Caskroom/miniforge/base/envs/haystack/lib/python3.10/site-packages/torch/nn/modules/module.py", line 1501, in _call_impl
    return forward_call(*args, **kwargs)
  File "/opt/homebrew/Caskroom/miniforge/base/envs/haystack/lib/python3.10/site-packages/torch/nn/modules/sparse.py", line 162, in forward
    return F.embedding(
  File "/opt/homebrew/Caskroom/miniforge/base/envs/haystack/lib/python3.10/site-packages/torch/nn/functional.py", line 2210, in embedding
    return torch.embedding(weight, input, padding_idx, scale_grad_by_freq, sparse)
IndexError: index out of range in self
```

**Expected behavior**
DPR should work with any transformer model.

**Additional context**
The issue is probably that we use `DPRQuestionEncoderTokenizerFast`/`DPRContextEncoderTokenizerFast` regardless of the model.

This came up in this discussion: https://github.com/deepset-ai/haystack/discussions/4876

**To Reproduce**
```python
from haystack.nodes import DensePassageRetriever
dpr = DensePassageRetriever(
    query_embedding_model="etalab-ia/dpr-question_encoder-fr_qa-camembert", 
    passage_embedding_model="etalab-ia/dpr-ctx_encoder-fr_qa-camembert"
)
dpr.embed_queries(queries=["Sample query."])
```

**FAQ Check**
- [x] Have you had a look at [our new FAQ page](https://docs.haystack.deepset.ai/docs/faq)?



Discussion:

Resolving patch:
diff --git a/haystack/nodes/retriever/dense.py b/haystack/nodes/retriever/dense.py
--- a/haystack/nodes/retriever/dense.py
+++ b/haystack/nodes/retriever/dense.py
@@ -19,13 +19,7 @@
 from torch.utils.data.sampler import SequentialSampler
 import pandas as pd
 from huggingface_hub import hf_hub_download
-from transformers import (
-    AutoConfig,
-    DPRContextEncoderTokenizerFast,
-    DPRQuestionEncoderTokenizerFast,
-    DPRContextEncoderTokenizer,
-    DPRQuestionEncoderTokenizer,
-)
+from transformers import AutoConfig, AutoTokenizer
 
 from haystack.errors import HaystackError
 from haystack.schema import Document, FilterType
@@ -191,7 +185,7 @@ def __init__(
             )
 
         # Init & Load Encoders
-        self.query_tokenizer = DPRQuestionEncoderTokenizerFast.from_pretrained(
+        self.query_tokenizer = AutoTokenizer.from_pretrained(
             pretrained_model_name_or_path=query_embedding_model,
             revision=model_version,
             do_lower_case=True,
@@ -203,7 +197,7 @@ def __init__(
             model_type="DPRQuestionEncoder",
             use_auth_token=use_auth_token,
         )
-        self.passage_tokenizer = DPRContextEncoderTokenizerFast.from_pretrained(
+        self.passage_tokenizer = AutoTokenizer.from_pretrained(
             pretrained_model_name_or_path=passage_embedding_model,
             revision=model_version,
             do_lower_case=True,
@@ -873,12 +867,8 @@ def __init__(
         self.embed_meta_fields = embed_meta_fields
         self.scale_score = scale_score
 
-        query_tokenizer_class = DPRQuestionEncoderTokenizerFast if use_fast else DPRQuestionEncoderTokenizer
-        passage_tokenizer_class = DPRContextEncoderTokenizerFast if use_fast else DPRContextEncoderTokenizer
-        table_tokenizer_class = DPRContextEncoderTokenizerFast if use_fast else DPRContextEncoderTokenizer
-
         # Init & Load Encoders
-        self.query_tokenizer = query_tokenizer_class.from_pretrained(
+        self.query_tokenizer = AutoTokenizer.from_pretrained(
             query_embedding_model,
             revision=model_version,
             do_lower_case=True,
@@ -888,7 +878,7 @@ def __init__(
         self.query_encoder = get_language_model(
             pretrained_model_name_or_path=query_embedding_model, revision=model_version, use_auth_token=use_auth_token
         )
-        self.passage_tokenizer = passage_tokenizer_class.from_pretrained(
+        self.passage_tokenizer = AutoTokenizer.from_pretrained(
             passage_embedding_model,
             revision=model_version,
             do_lower_case=True,
@@ -898,7 +888,7 @@ def __init__(
         self.passage_encoder = get_language_model(
             pretrained_model_name_or_path=passage_embedding_model, revision=model_version, use_auth_token=use_auth_token
         )
-        self.table_tokenizer = table_tokenizer_class.from_pretrained(
+        self.table_tokenizer = AutoTokenizer.from_pretrained(
             table_embedding_model,
             revision=model_version,
             do_lower_case=True,


Test patch:
diff --git a/test/nodes/test_retriever.py b/test/nodes/test_retriever.py
--- a/test/nodes/test_retriever.py
+++ b/test/nodes/test_retriever.py
@@ -10,7 +10,7 @@
 import requests
 from boilerpy3.extractors import ArticleExtractor
 from pandas.testing import assert_frame_equal
-from transformers import DPRContextEncoderTokenizerFast, DPRQuestionEncoderTokenizerFast
+from transformers import PreTrainedTokenizerFast
 
 
 try:
@@ -578,8 +578,8 @@ def sum_params(model):
     assert loaded_retriever.processor.max_seq_len_query == 64
 
     # Tokenizer
-    assert isinstance(loaded_retriever.passage_tokenizer, DPRContextEncoderTokenizerFast)
-    assert isinstance(loaded_retriever.query_tokenizer, DPRQuestionEncoderTokenizerFast)
+    assert isinstance(loaded_retriever.passage_tokenizer, PreTrainedTokenizerFast)
+    assert isinstance(loaded_retriever.query_tokenizer, PreTrainedTokenizerFast)
     assert loaded_retriever.passage_tokenizer.do_lower_case == True
     assert loaded_retriever.query_tokenizer.do_lower_case == True
     assert loaded_retriever.passage_tokenizer.vocab_size == 30522
@@ -621,9 +621,9 @@ def sum_params(model):
     assert loaded_retriever.processor.max_seq_len_query == 64
 
     # Tokenizer
-    assert isinstance(loaded_retriever.passage_tokenizer, DPRContextEncoderTokenizerFast)
-    assert isinstance(loaded_retriever.table_tokenizer, DPRContextEncoderTokenizerFast)
-    assert isinstance(loaded_retriever.query_tokenizer, DPRQuestionEncoderTokenizerFast)
+    assert isinstance(loaded_retriever.passage_tokenizer, PreTrainedTokenizerFast)
+    assert isinstance(loaded_retriever.table_tokenizer, PreTrainedTokenizerFast)
+    assert isinstance(loaded_retriever.query_tokenizer, PreTrainedTokenizerFast)
     assert loaded_retriever.passage_tokenizer.do_lower_case == True
     assert loaded_retriever.table_tokenizer.do_lower_case == True
     assert loaded_retriever.query_tokenizer.do_lower_case == True