Repository: huggingface/transformers
Pull request: Future annotations break FastAPI

Unfortunately, `from __future__ import annotations` breaks pydantic/FastAPI -> everything results in "422: unprocessable entity".

The following is therefore not possible: `"PreTrainedTokenizerFast" | None`, reverting to an `Optional`.

Changed files:
filename: benchmark_v2/framework/benchmark_runner.py
patch: @@ -10,7 +10,6 @@
 from queue import Queue
 from typing import Any
 
-import numpy as np
 import torch
 from datasets import Dataset
 from huggingface_hub import HfApi

filename: src/transformers/cli/serve.py
patch: @@ -11,7 +11,6 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
-from __future__ import annotations
 
 import asyncio
 import base64
@@ -316,9 +315,9 @@ class TimedModel:
 
     def __init__(
         self,
-        model: PreTrainedModel,
+        model: "PreTrainedModel",
         timeout_seconds: int,
-        processor: Union[ProcessorMixin, PreTrainedTokenizerFast] | None = None,
+        processor: Union["ProcessorMixin", "PreTrainedTokenizerFast"] | None = None,
     ):
         self.model = model
         self._name_or_path = str(model.name_or_path)
@@ -666,7 +665,7 @@ def build_chat_completion_chunk(
         finish_reason: str | None = None,
         tool_calls: list[ChoiceDeltaToolCall] | None = None,
         decode_stream: DecodeStream | None = None,
-        tokenizer: PreTrainedTokenizerFast | None = None,
+        tokenizer: Optional["PreTrainedTokenizerFast"] = None,
     ) -> ChatCompletionChunk:
         """
         Builds a chunk of a streaming OpenAI Chat Completion response.
@@ -914,7 +913,7 @@ def cancellation_wrapper_buffer(_request_id):
             return JSONResponse(json_chunk, media_type="application/json")
 
     @staticmethod
-    def get_model_modality(model: PreTrainedModel) -> Modality:
+    def get_model_modality(model: "PreTrainedModel") -> Modality:
         from transformers.models.auto.modeling_auto import (
             MODEL_FOR_CAUSAL_LM_MAPPING_NAMES,
             MODEL_FOR_IMAGE_TEXT_TO_TEXT_MAPPING_NAMES,
@@ -1792,7 +1791,9 @@ def _load_model_and_data_processor(self, model_id_and_revision: str):
         logger.info(f"Loaded model {model_id_and_revision}")
         return model, data_processor
 
-    def load_model_and_processor(self, model_id_and_revision: str) -> tuple[PreTrainedModel, PreTrainedTokenizerFast]:
+    def load_model_and_processor(
+        self, model_id_and_revision: str
+    ) -> tuple["PreTrainedModel", "PreTrainedTokenizerFast"]:
         """
         Loads the text model and processor from the given model ID and revision into the ServeCommand instance.
 
@@ -1817,7 +1818,7 @@ def load_model_and_processor(self, model_id_and_revision: str) -> tuple[PreTrain
 
         return model, processor
 
-    def load_audio_model_and_processor(self, model_id_and_revision: str) -> tuple[PreTrainedModel, ProcessorMixin]:
+    def load_audio_model_and_processor(self, model_id_and_revision: str) -> tuple["PreTrainedModel", "ProcessorMixin"]:
         """
         Loads the audio model and processor from the given model ID and revision into the ServeCommand instance.