From 9d6774f32d7cda9f2b59b94083b01622dfaedcc7 Mon Sep 17 00:00:00 2001 From: Defne Dilbaz Date: Mon, 16 Dec 2024 12:02:36 -0500 Subject: [PATCH] Add Qwen model [#52] (#121) * Add Qwen (model) [#52] * Add Qwen to nightly tests --- .github/workflows/run-model-tests.yml | 2 +- tests/models/Qwen/test_qwen2_casual_lm.py | 64 +++++++++++++++++++ .../Qwen/test_qwen2_token_classification.py | 59 +++++++++++++++++ tt_torch/dynamo/passes.py | 2 +- 4 files changed, 125 insertions(+), 2 deletions(-) create mode 100644 tests/models/Qwen/test_qwen2_casual_lm.py create mode 100644 tests/models/Qwen/test_qwen2_token_classification.py diff --git a/.github/workflows/run-model-tests.yml b/.github/workflows/run-model-tests.yml index 5cc95ab8..9c766e21 100644 --- a/.github/workflows/run-model-tests.yml +++ b/.github/workflows/run-model-tests.yml @@ -16,7 +16,7 @@ jobs: build: [ {runs-on: n150, n300, name: "run1", test_names: "stable_diffusion"}, {runs-on: n150, n300, name: "run2", test_names: "MobileNetV2, clip, flan_t5, mlpmixer, resnet, vilt, albert, codegen, glpn_kitti, mnist, resnet50, t5, whisper, autoencoder_conv, deit, gpt2, mobilenet_ssd, roberta, timm, xglm, autoencoder_linear, detr, gpt_neo, musicgen_small, segformer, torchvision, yolos, RMBG"}, - {runs-on: n300, n150, name: "run3", test_names: "beit, distilbert, hand_landmark, openpose, segment_anything, unet, yolov3, bert, dpr, hardnet, opt, speecht5_tts, unet_brain, yolov5, bloom, falcon, llama, perceiver_io, squeeze_bert, unet_carvana, mgp-str-base"}, + {runs-on: n300, n150, name: "run3", test_names: "beit, distilbert, hand_landmark, openpose, segment_anything, unet, yolov3, bert, dpr, hardnet, opt, speecht5_tts, unet_brain, yolov5, bloom, falcon, llama, perceiver_io, squeeze_bert, unet_carvana, mgp-str-base, Qwen"}, ] runs-on: - ${{ matrix.build.runs-on }} diff --git a/tests/models/Qwen/test_qwen2_casual_lm.py b/tests/models/Qwen/test_qwen2_casual_lm.py new file mode 100644 index 00000000..406e58ab --- /dev/null +++ b/tests/models/Qwen/test_qwen2_casual_lm.py @@ -0,0 +1,64 @@ +# SPDX-FileCopyrightText: (c) 2024 Tenstorrent AI ULC +# +# SPDX-License-Identifier: Apache-2.0 +# Reference: https://huggingface.co/Qwen/Qwen2.5-1.5B + +from transformers import AutoTokenizer, Qwen2ForCausalLM, GenerationConfig +import torch +import pytest +from tests.utils import ModelTester + + +class ThisTester(ModelTester): + def _load_model(self): + model = Qwen2ForCausalLM.from_pretrained( + self.model_name, torch_dtype=torch.bfloat16 + ) + self.tokenizer = AutoTokenizer.from_pretrained( + self.model_name, torch_dtype=torch.bfloat16 + ) + return model.generate + + def _load_inputs(self): + + self.text = "Hey, are you conscious? Can you talk to me?" + input_ids = self.tokenizer(self.text, return_tensors="pt").input_ids + generation_config = GenerationConfig(max_length=30) + arguments = {"input_ids": input_ids, "generation_config": generation_config} + return arguments + + def set_model_eval(self, model): + return model + + +@pytest.mark.parametrize( + "mode", + ["eval", "train"], +) +@pytest.mark.parametrize( + "model_name", + [ + "Qwen/Qwen2.5-1.5B", + ], +) +def test_qwen2_casual_lm(record_property, model_name, mode): + if mode == "train": + pytest.skip() + record_property("model_name", model_name) + record_property("mode", mode) + + tester = ThisTester(model_name, mode) + results = tester.test_model() + + if mode == "eval": + gen_text = tester.tokenizer.batch_decode( + results, + skip_special_tokens=True, + clean_up_tokenization_spaces=False, + )[0] + + print( + f"Model: {model_name} | Input: {tester.text} | Generated Text: {gen_text}" + ) + + record_property("torch_ttnn", (tester, results)) diff --git a/tests/models/Qwen/test_qwen2_token_classification.py b/tests/models/Qwen/test_qwen2_token_classification.py new file mode 100644 index 00000000..fde18c42 --- /dev/null +++ b/tests/models/Qwen/test_qwen2_token_classification.py @@ -0,0 +1,59 @@ +# SPDX-FileCopyrightText: (c) 2024 Tenstorrent AI ULC +# +# SPDX-License-Identifier: Apache-2.0 +from transformers import AutoTokenizer, Qwen2ForTokenClassification +import torch +import pytest +from tests.utils import ModelTester + + +class ThisTester(ModelTester): + def _load_model(self): + return Qwen2ForTokenClassification.from_pretrained( + self.model_name, torch_dtype=torch.bfloat16 + ) + + def _load_inputs(self): + self.tokenizer = AutoTokenizer.from_pretrained( + self.model_name, torch_dtype=torch.bfloat16 + ) + self.text = "HuggingFace is a company based in Paris and New York." + self.inputs = self.tokenizer( + self.text, add_special_tokens=False, return_tensors="pt" + ) + return self.inputs + + +@pytest.mark.parametrize( + "mode", + ["eval", "train"], +) +@pytest.mark.parametrize( + "model_name", + [ + "Qwen/Qwen2-7B", + ], +) +def test_qwen2_token_classification(record_property, model_name, mode): + if mode == "train": + pytest.skip() + record_property("model_name", model_name) + record_property("mode", mode) + + tester = ThisTester(model_name, mode) + with torch.no_grad(): + results = tester.test_model() + + if mode == "eval": + logits = results.logits + predicted_token_class_ids = logits.argmax(-1) + predicted_tokens_classes = [ + tester.model.config.id2label[t.item()] for t in predicted_token_class_ids[0] + ] + input_ids = tester.inputs["input_ids"] + tokens = tester.tokenizer.convert_ids_to_tokens(input_ids[0]) + print( + f"Model: {model_name} | Tokens: {tokens} | Predictions: {predicted_tokens_classes}" + ) + + record_property("torch_ttnn", (tester, results)) diff --git a/tt_torch/dynamo/passes.py b/tt_torch/dynamo/passes.py index ab2b3cf8..bd2c6e28 100644 --- a/tt_torch/dynamo/passes.py +++ b/tt_torch/dynamo/passes.py @@ -2,11 +2,11 @@ # # SPDX-License-Identifier: Apache-2.0 import torch +import traceback from torch.fx.experimental.proxy_tensor import make_fx from torch._decomp import get_decompositions from torch.func import functionalize from typing import List, Optional -import traceback from .decompositions import DEFAULT_DECOMPOSITIONS