prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  HuggingFace model should update word embeddings dimension according to tokenizer
  ** To reproduce
  
  Steps to reproduce the behavior:
  
  Right now if I call 
  
  ```
  model = transformers.AutoModelForCausalLM.from_pretrained('bigscience/bloom-560m')
  tokenizer = transformers.AutoTokenizer.from_pretrained('gpt2')
  
  model = HuggingFaceModel(model=model, tokenizer=tokenizer)
  ```
  
  The bloom model will have a [250880, 1024] dim word embedding matrix and a vocab size of 250880 even though a gpt2 tokenizer with vocab size of 50257 is used.
  
  ## Expected behavior
  
  The class HuggingFaceModel needs to update word embedding matrix if a tokenizer is supplied.
  
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `composer/models/huggingface.py`
  Content:
  ```
  1 # Copyright 2022 MosaicML Composer authors
  2 # SPDX-License-Identifier: Apache-2.0
  3 
  4 """A wrapper class that converts 🤗 Transformers models to composer models"""
  5 
  6 from __future__ import annotations
  7 
  8 from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
  9 
  10 from torchmetrics import Metric
  11 
  12 from composer.models.base import ComposerModel
  13 from composer.utils.import_helpers import MissingConditionalImportError
  14 
  15 if TYPE_CHECKING:
  16     import transformers
  17 
  18 __all__ = ['HuggingFaceModel']
  19 
  20 
  21 class HuggingFaceModel(ComposerModel):
  22     """
  23     A wrapper class that converts 🤗 Transformers models to composer models.
  24 
  25     Args:
  26         model (transformers.PreTrainedModel): A 🤗 Transformers model.
  27         tokenizer (transformers.PreTrainedTokenizer): Tokenizer used to prepare the dataset and validate model inputs during training. Default ``None``.
  28         use_logits (bool, optional): If True, the model's output logits will be used to calculate validation metrics. Else, metrics will be inferred from the HuggingFaceModel directly. Default: ``False``
  29         metrics (list[Metric], optional): list of torchmetrics to apply to the output of `validate`. Default: ``None``.
  30     .. warning:: This wrapper is designed to work with 🤗 datasets that define a `labels` column.
  31 
  32     Example:
  33 
  34     .. testcode::
  35 
  36         import transformers
  37         from composer.models import HuggingFaceModel
  38 
  39         hf_model = transformers.AutoModelForSequenceClassification.from_pretrained('bert-base-uncased', num_labels=2)
  40         model = HuggingFaceModel(hf_model)
  41     """
  42 
  43     def __init__(self,
  44                  model: transformers.PreTrainedModel,
  45                  tokenizer: Optional[Union[transformers.PreTrainedTokenizer,
  46                                            transformers.PreTrainedTokenizerFast]] = None,
  47                  use_logits: Optional[bool] = False,
  48                  metrics: Optional[List[Metric]] = None) -> None:
  49         try:
  50             import transformers
  51         except ImportError as e:
  52             raise MissingConditionalImportError(extra_deps_group='nlp', conda_package='transformers') from e
  53 
  54         super().__init__()
  55         self.model = model
  56         self.config = model.config
  57 
  58         # the set of inputs that a model expects inferred from the model type or
  59         # tokenizer if provided
  60         if tokenizer is None:
  61             if isinstance(self.model.base_model, transformers.GPT2Model):
  62                 self.model_inputs = {'input_ids', 'attention_mask'}
  63             elif isinstance(self.model.base_model, transformers.BertModel):
  64                 self.model_inputs = {'input_ids', 'attention_mask', 'token_type_ids'}
  65         else:
  66             assert tokenizer.model_input_names is not None, 'the tokenizer should have a model input name'
  67             self.model_inputs = set(tokenizer.model_input_names)
  68 
  69         self.use_logits = use_logits
  70 
  71         self.train_metrics = None
  72         self.val_metrics = None
  73 
  74         if metrics:
  75             self.train_metrics = {metric.__class__.__name__: metric for metric in metrics}
  76             self.val_metrics = {metric.__class__.__name__: metric for metric in metrics}
  77 
  78         self.labels = None  # set in eval_forward() if exists
  79 
  80     def forward(self, batch):
  81         for key in self.model_inputs:
  82             if key not in batch.keys():
  83                 raise ValueError(f'Batch missing key: {key}')
  84 
  85         output = self.model(**batch)  # type: ignore (thirdparty)
  86         return output
  87 
  88     def loss(self, outputs, batch):
  89         return outputs['loss']
  90 
  91     def eval_forward(self, batch, outputs: Optional[Any] = None):
  92         output = outputs if outputs else self.forward(batch)
  93         if self.use_logits:
  94             self.labels = batch.pop('labels')
  95             output = output['logits']
  96 
  97             # if we are in the single class case, then remove the classes dimension
  98             if output.shape[1] == 1:
  99                 output = output.squeeze(dim=1)
  100 
  101         return output
  102 
  103     def get_metrics(self, is_train: bool = False) -> Dict[str, Metric]:
  104         if is_train:
  105             metrics = self.train_metrics
  106         else:
  107             metrics = self.val_metrics
  108 
  109         return metrics if metrics else {}
  110 
  111     def update_metric(self, batch: Any, outputs: Any, metric: Metric) -> None:
  112         metric.update(outputs, self.labels)
  113 
  114     def get_model_inputs(self):
  115         """Returns a set of inputs that the model expects in the forward pass.
  116         If an algorithm wants to interact with the model inputs (for instance,
  117         popping the labels for a custom loss fn, or adding attention head masks
  118         for head pruning, it must access self.set_model_inputs().
  119         Returns:
  120             model_inputs: The set of keys that are expected in the Mapping used to compute the forward pass.
  121         """
  122 
  123         return self.model_inputs
  124
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/composer/models/huggingface.py b/composer/models/huggingface.py
  --- a/composer/models/huggingface.py
  +++ b/composer/models/huggingface.py
  @@ -5,6 +5,7 @@
   
   from __future__ import annotations
   
  +import logging
   from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
   
   from torchmetrics import Metric
  @@ -15,6 +16,8 @@
   if TYPE_CHECKING:
       import transformers
   
  +log = logging.getLogger(__name__)
  +
   __all__ = ['HuggingFaceModel']
   
   
  @@ -66,6 +69,13 @@
               assert tokenizer.model_input_names is not None, 'the tokenizer should have a model input name'
               self.model_inputs = set(tokenizer.model_input_names)
   
  +            if self.config.vocab_size != len(tokenizer):
  +                # set model's word embedding matrix and final lm_head to vocab size according to tokenizer
  +                log.warning(
  +                    f'The number of tokens in the tokenizer and the number of tokens in the model are different.'
  +                    f' Resizing the model tokenizer to {len(tokenizer)} from {self.config.vocab_size}.')
  +                self.model.resize_token_embeddings(len(tokenizer))
  +
           self.use_logits = use_logits
   
           self.train_metrics = None
  
verification_info: {"golden_diff": "diff --git a/composer/models/huggingface.py b/composer/models/huggingface.py\n--- a/composer/models/huggingface.py\n+++ b/composer/models/huggingface.py\n@@ -5,6 +5,7 @@\n \n from __future__ import annotations\n \n+import logging\n from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union\n \n from torchmetrics import Metric\n@@ -15,6 +16,8 @@\n if TYPE_CHECKING:\n     import transformers\n \n+log = logging.getLogger(__name__)\n+\n __all__ = ['HuggingFaceModel']\n \n \n@@ -66,6 +69,13 @@\n             assert tokenizer.model_input_names is not None, 'the tokenizer should have a model input name'\n             self.model_inputs = set(tokenizer.model_input_names)\n \n+            if self.config.vocab_size != len(tokenizer):\n+                # set model's word embedding matrix and final lm_head to vocab size according to tokenizer\n+                log.warning(\n+                    f'The number of tokens in the tokenizer and the number of tokens in the model are different.'\n+                    f' Resizing the model tokenizer to {len(tokenizer)} from {self.config.vocab_size}.')\n+                self.model.resize_token_embeddings(len(tokenizer))\n+\n         self.use_logits = use_logits\n \n         self.train_metrics = None\n", "issue": "HuggingFace model should update word embeddings dimension according to tokenizer\n** To reproduce\r\n\r\nSteps to reproduce the behavior:\r\n\r\nRight now if I call \r\n\r\n```\r\nmodel = transformers.AutoModelForCausalLM.from_pretrained('bigscience/bloom-560m')\r\ntokenizer = transformers.AutoTokenizer.from_pretrained('gpt2')\r\n\r\nmodel = HuggingFaceModel(model=model, tokenizer=tokenizer)\r\n```\r\n\r\nThe bloom model will have a [250880, 1024] dim word embedding matrix and a vocab size of 250880 even though a gpt2 tokenizer with vocab size of 50257 is used.\r\n\r\n## Expected behavior\r\n\r\nThe class HuggingFaceModel needs to update word embedding matrix if a tokenizer is supplied.\r\n\r\n\n", "before_files": [{"content": "# Copyright 2022 MosaicML Composer authors\n# SPDX-License-Identifier: Apache-2.0\n\n\"\"\"A wrapper class that converts \ud83e\udd17 Transformers models to composer models\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import TYPE_CHECKING, Any, Dict, List, Optional, Union\n\nfrom torchmetrics import Metric\n\nfrom composer.models.base import ComposerModel\nfrom composer.utils.import_helpers import MissingConditionalImportError\n\nif TYPE_CHECKING:\n    import transformers\n\n__all__ = ['HuggingFaceModel']\n\n\nclass HuggingFaceModel(ComposerModel):\n    \"\"\"\n    A wrapper class that converts \ud83e\udd17 Transformers models to composer models.\n\n    Args:\n        model (transformers.PreTrainedModel): A \ud83e\udd17 Transformers model.\n        tokenizer (transformers.PreTrainedTokenizer): Tokenizer used to prepare the dataset and validate model inputs during training. Default ``None``.\n        use_logits (bool, optional): If True, the model's output logits will be used to calculate validation metrics. Else, metrics will be inferred from the HuggingFaceModel directly. Default: ``False``\n        metrics (list[Metric], optional): list of torchmetrics to apply to the output of `validate`. Default: ``None``.\n    .. warning:: This wrapper is designed to work with \ud83e\udd17 datasets that define a `labels` column.\n\n    Example:\n\n    .. testcode::\n\n        import transformers\n        from composer.models import HuggingFaceModel\n\n        hf_model = transformers.AutoModelForSequenceClassification.from_pretrained('bert-base-uncased', num_labels=2)\n        model = HuggingFaceModel(hf_model)\n    \"\"\"\n\n    def __init__(self,\n                 model: transformers.PreTrainedModel,\n                 tokenizer: Optional[Union[transformers.PreTrainedTokenizer,\n                                           transformers.PreTrainedTokenizerFast]] = None,\n                 use_logits: Optional[bool] = False,\n                 metrics: Optional[List[Metric]] = None) -> None:\n        try:\n            import transformers\n        except ImportError as e:\n            raise MissingConditionalImportError(extra_deps_group='nlp', conda_package='transformers') from e\n\n        super().__init__()\n        self.model = model\n        self.config = model.config\n\n        # the set of inputs that a model expects inferred from the model type or\n        # tokenizer if provided\n        if tokenizer is None:\n            if isinstance(self.model.base_model, transformers.GPT2Model):\n                self.model_inputs = {'input_ids', 'attention_mask'}\n            elif isinstance(self.model.base_model, transformers.BertModel):\n                self.model_inputs = {'input_ids', 'attention_mask', 'token_type_ids'}\n        else:\n            assert tokenizer.model_input_names is not None, 'the tokenizer should have a model input name'\n            self.model_inputs = set(tokenizer.model_input_names)\n\n        self.use_logits = use_logits\n\n        self.train_metrics = None\n        self.val_metrics = None\n\n        if metrics:\n            self.train_metrics = {metric.__class__.__name__: metric for metric in metrics}\n            self.val_metrics = {metric.__class__.__name__: metric for metric in metrics}\n\n        self.labels = None  # set in eval_forward() if exists\n\n    def forward(self, batch):\n        for key in self.model_inputs:\n            if key not in batch.keys():\n                raise ValueError(f'Batch missing key: {key}')\n\n        output = self.model(**batch)  # type: ignore (thirdparty)\n        return output\n\n    def loss(self, outputs, batch):\n        return outputs['loss']\n\n    def eval_forward(self, batch, outputs: Optional[Any] = None):\n        output = outputs if outputs else self.forward(batch)\n        if self.use_logits:\n            self.labels = batch.pop('labels')\n            output = output['logits']\n\n            # if we are in the single class case, then remove the classes dimension\n            if output.shape[1] == 1:\n                output = output.squeeze(dim=1)\n\n        return output\n\n    def get_metrics(self, is_train: bool = False) -> Dict[str, Metric]:\n        if is_train:\n            metrics = self.train_metrics\n        else:\n            metrics = self.val_metrics\n\n        return metrics if metrics else {}\n\n    def update_metric(self, batch: Any, outputs: Any, metric: Metric) -> None:\n        metric.update(outputs, self.labels)\n\n    def get_model_inputs(self):\n        \"\"\"Returns a set of inputs that the model expects in the forward pass.\n        If an algorithm wants to interact with the model inputs (for instance,\n        popping the labels for a custom loss fn, or adding attention head masks\n        for head pruning, it must access self.set_model_inputs().\n        Returns:\n            model_inputs: The set of keys that are expected in the Mapping used to compute the forward pass.\n        \"\"\"\n\n        return self.model_inputs\n", "path": "composer/models/huggingface.py"}], "after_files": [{"content": "# Copyright 2022 MosaicML Composer authors\n# SPDX-License-Identifier: Apache-2.0\n\n\"\"\"A wrapper class that converts \ud83e\udd17 Transformers models to composer models\"\"\"\n\nfrom __future__ import annotations\n\nimport logging\nfrom typing import TYPE_CHECKING, Any, Dict, List, Optional, Union\n\nfrom torchmetrics import Metric\n\nfrom composer.models.base import ComposerModel\nfrom composer.utils.import_helpers import MissingConditionalImportError\n\nif TYPE_CHECKING:\n    import transformers\n\nlog = logging.getLogger(__name__)\n\n__all__ = ['HuggingFaceModel']\n\n\nclass HuggingFaceModel(ComposerModel):\n    \"\"\"\n    A wrapper class that converts \ud83e\udd17 Transformers models to composer models.\n\n    Args:\n        model (transformers.PreTrainedModel): A \ud83e\udd17 Transformers model.\n        tokenizer (transformers.PreTrainedTokenizer): Tokenizer used to prepare the dataset and validate model inputs during training. Default ``None``.\n        use_logits (bool, optional): If True, the model's output logits will be used to calculate validation metrics. Else, metrics will be inferred from the HuggingFaceModel directly. Default: ``False``\n        metrics (list[Metric], optional): list of torchmetrics to apply to the output of `validate`. Default: ``None``.\n    .. warning:: This wrapper is designed to work with \ud83e\udd17 datasets that define a `labels` column.\n\n    Example:\n\n    .. testcode::\n\n        import transformers\n        from composer.models import HuggingFaceModel\n\n        hf_model = transformers.AutoModelForSequenceClassification.from_pretrained('bert-base-uncased', num_labels=2)\n        model = HuggingFaceModel(hf_model)\n    \"\"\"\n\n    def __init__(self,\n                 model: transformers.PreTrainedModel,\n                 tokenizer: Optional[Union[transformers.PreTrainedTokenizer,\n                                           transformers.PreTrainedTokenizerFast]] = None,\n                 use_logits: Optional[bool] = False,\n                 metrics: Optional[List[Metric]] = None) -> None:\n        try:\n            import transformers\n        except ImportError as e:\n            raise MissingConditionalImportError(extra_deps_group='nlp', conda_package='transformers') from e\n\n        super().__init__()\n        self.model = model\n        self.config = model.config\n\n        # the set of inputs that a model expects inferred from the model type or\n        # tokenizer if provided\n        if tokenizer is None:\n            if isinstance(self.model.base_model, transformers.GPT2Model):\n                self.model_inputs = {'input_ids', 'attention_mask'}\n            elif isinstance(self.model.base_model, transformers.BertModel):\n                self.model_inputs = {'input_ids', 'attention_mask', 'token_type_ids'}\n        else:\n            assert tokenizer.model_input_names is not None, 'the tokenizer should have a model input name'\n            self.model_inputs = set(tokenizer.model_input_names)\n\n            if self.config.vocab_size != len(tokenizer):\n                # set model's word embedding matrix and final lm_head to vocab size according to tokenizer\n                log.warning(\n                    f'The number of tokens in the tokenizer and the number of tokens in the model are different.'\n                    f' Resizing the model tokenizer to {len(tokenizer)} from {self.config.vocab_size}.')\n                self.model.resize_token_embeddings(len(tokenizer))\n\n        self.use_logits = use_logits\n\n        self.train_metrics = None\n        self.val_metrics = None\n\n        if metrics:\n            self.train_metrics = {metric.__class__.__name__: metric for metric in metrics}\n            self.val_metrics = {metric.__class__.__name__: metric for metric in metrics}\n\n        self.labels = None  # set in eval_forward() if exists\n\n    def forward(self, batch):\n        for key in self.model_inputs:\n            if key not in batch.keys():\n                raise ValueError(f'Batch missing key: {key}')\n\n        output = self.model(**batch)  # type: ignore (thirdparty)\n        return output\n\n    def loss(self, outputs, batch):\n        return outputs['loss']\n\n    def eval_forward(self, batch, outputs: Optional[Any] = None):\n        output = outputs if outputs else self.forward(batch)\n        if self.use_logits:\n            self.labels = batch.pop('labels')\n            output = output['logits']\n\n            # if we are in the single class case, then remove the classes dimension\n            if output.shape[1] == 1:\n                output = output.squeeze(dim=1)\n\n        return output\n\n    def get_metrics(self, is_train: bool = False) -> Dict[str, Metric]:\n        if is_train:\n            metrics = self.train_metrics\n        else:\n            metrics = self.val_metrics\n\n        return metrics if metrics else {}\n\n    def update_metric(self, batch: Any, outputs: Any, metric: Metric) -> None:\n        metric.update(outputs, self.labels)\n\n    def get_model_inputs(self):\n        \"\"\"Returns a set of inputs that the model expects in the forward pass.\n        If an algorithm wants to interact with the model inputs (for instance,\n        popping the labels for a custom loss fn, or adding attention head masks\n        for head pruning, it must access self.set_model_inputs().\n        Returns:\n            model_inputs: The set of keys that are expected in the Mapping used to compute the forward pass.\n        \"\"\"\n\n        return self.model_inputs\n", "path": "composer/models/huggingface.py"}]}