Download code/models/tt_transformers/tests/test_decoder_prefill.py from DeAIafdeling/qwen38-flash-next: direct link, hf CLI and curl.
- Browser
- Download file 8.39 kB
-
https://huggingface.co/DeAIafdeling/qwen38-flash-next/resolve/main/code/models/tt_transformers/tests/test_decoder_prefill.py
- Command line
-
hf download hf://DeAIafdeling/qwen38-flash-next/code/models/tt_transformers/tests/test_decoder_prefill.py
-
curl -L -o test_decoder_prefill.py https://huggingface.co/DeAIafdeling/qwen38-flash-next/resolve/main/code/models/tt_transformers/tests/test_decoder_prefill.py
8.39 kB
| # SPDX-FileCopyrightText: © 2023 Tenstorrent USA, Inc. | |
| # SPDX-License-Identifier: Apache-2.0 | |
| import os | |
| import pytest | |
| import torch | |
| from loguru import logger | |
| import ttnn | |
| from models.common.utility_functions import comp_allclose, comp_pcc | |
| from models.tt_transformers.tests.test_utils import get_ref_model_dype | |
| from models.tt_transformers.tt.ccl import TT_CCL | |
| from models.tt_transformers.tt.common import Mode, PagedAttentionConfig, get_rot_transformation_mat, precompute_freqs | |
| from models.tt_transformers.tt.decoder import TransformerBlock | |
| from models.tt_transformers.tt.model_config import ModelArgs | |
| from models.tt_transformers.tt.prefetcher import Prefetcher | |
| from models.tt_transformers.tt.rope import get_rot_mats, get_rot_mats_hf | |
| def test_decoder_inference( | |
| max_seq_len, | |
| paged_attention, | |
| page_params, | |
| mesh_device, | |
| reset_seeds, | |
| ensure_gc, | |
| use_prefetcher, | |
| ): | |
| model_name_env = os.getenv("HF_MODEL") | |
| if max_seq_len > 256 and model_name_env and "Mistral-7B" in model_name_env: | |
| pytest.skip( | |
| "Mistral-7B models do not support max_seq_len > 256. See issue: https://github.com/tenstorrent/tt-metal/issues/19806" | |
| ) | |
| dtype = ttnn.bfloat8_b | |
| batch_size = 1 # For prefill we only support batch_size = 1 | |
| num_tensors = 0 | |
| prefetcher = Prefetcher(mesh_device, num_tensors=num_tensors, num_layers=1) if use_prefetcher else None | |
| if use_prefetcher: | |
| prefetcher.init(mode=Mode.PREFILL) | |
| model_args = ModelArgs( | |
| mesh_device, | |
| max_batch_size=batch_size, | |
| max_seq_len=max_seq_len, | |
| cache_hf=True, | |
| prefetcher=prefetcher, | |
| use_hf_rope=False, | |
| ) | |
| model_args.n_layers = 1 | |
| state_dict = model_args.load_state_dict() | |
| reference_model = model_args.reference_decoder(load_checkpoint=True) | |
| generation_start_pos = 0 | |
| generation_length = 1 | |
| all_tests_pass = True | |
| rot_mats_fn = get_rot_mats_hf if model_args.use_hf_rope else get_rot_mats | |
| # pre-compute the rotational embedding matrix and send to device | |
| rot_mats = rot_mats_fn( | |
| head_dim=model_args.head_dim, | |
| device=mesh_device, | |
| seq_len=max_seq_len, | |
| theta=model_args.rope_theta, | |
| rope_scaling=model_args.rope_scaling, | |
| ) | |
| if model_args.rope_theta_local is not None: | |
| rot_mats_local = get_rot_mats( | |
| head_dim=model_args.head_dim, | |
| device=mesh_device, | |
| seq_len=max_seq_len, | |
| theta=model_args.rope_theta_local, | |
| rope_scaling=None, | |
| ) | |
| else: | |
| rot_mats_local = None | |
| transformation_mats = {} | |
| if not model_args.use_hf_rope: | |
| transformation_mat_torch = get_rot_transformation_mat(model_args.head_dim) | |
| transformation_mats_prefill = ttnn.as_tensor( | |
| transformation_mat_torch, | |
| dtype=ttnn.bfloat16, | |
| layout=ttnn.TILE_LAYOUT, | |
| device=mesh_device, | |
| memory_config=ttnn.DRAM_MEMORY_CONFIG, | |
| mesh_mapper=ttnn.ReplicateTensorToMesh(mesh_device), | |
| ) | |
| transformation_mats = {"prefill": transformation_mats_prefill} | |
| # Setup page table | |
| page_table_tt = None | |
| paged_attention_config = None | |
| if paged_attention: | |
| paged_attention_config = PagedAttentionConfig( | |
| block_size=page_params["page_block_size"], | |
| max_num_blocks=page_params["page_max_num_blocks"], | |
| ) | |
| # Implied shuffling of blocks | |
| permutation = torch.randperm(paged_attention_config.max_num_blocks) | |
| # Page table which maps virtual blocks to physical | |
| reverse_permutation = torch.argsort(permutation) | |
| page_table = reverse_permutation.reshape( | |
| model_args.max_batch_size, paged_attention_config.max_num_blocks // model_args.max_batch_size | |
| ) | |
| page_table_tt = ttnn.from_torch( | |
| page_table, | |
| device=mesh_device, | |
| dtype=ttnn.int32, | |
| layout=ttnn.ROW_MAJOR_LAYOUT, | |
| mesh_mapper=ttnn.ReplicateTensorToMesh(mesh_device), | |
| ) | |
| # Initialize TT model | |
| tt_ccl = TT_CCL(mesh_device) | |
| tt_model = TransformerBlock( | |
| mesh_device=mesh_device, | |
| tt_ccl=tt_ccl, | |
| state_dict=state_dict, | |
| weight_cache_path=model_args.weight_cache_path(dtype), | |
| layer_num=0, | |
| dtype=dtype, | |
| transformation_mats=transformation_mats, | |
| args=model_args, | |
| paged_attention_config=paged_attention_config, | |
| prefetcher=prefetcher, | |
| ) | |
| for i in range(generation_length): | |
| logger.info(f"[Decoder] Generating token {i}") | |
| pt_decode_input = ( | |
| torch.rand( | |
| batch_size, | |
| max_seq_len, | |
| model_args.dim, | |
| dtype=get_ref_model_dype(reference_model, model_args.model_name), | |
| ) | |
| * 2 | |
| ) - 1 | |
| tt_decode_input = pt_decode_input.clone() | |
| decode_input = model_args.prepare_residual_tensor_prefill( | |
| tt_decode_input, | |
| ) | |
| positions = torch.LongTensor(range(max_seq_len)) | |
| cos, sin = precompute_freqs( | |
| model_args.head_dim, | |
| model_args.max_seq_len * 2, | |
| model_args.rope_theta, | |
| model_args.rope_scaling.factor if model_args.rope_scaling else None, | |
| model_args.rope_scaling.original_max_position_embeddings if model_args.rope_scaling else None, | |
| model_args.rope_scaling.rope_type.value if model_args.rope_scaling else "llama3", | |
| ) | |
| freqs_cis_i = torch.complex(cos, sin)[positions] | |
| # Reference model | |
| attn_mask = torch.triu(torch.full((max_seq_len, max_seq_len), torch.finfo(torch.float32).min), diagonal=1) | |
| if ( | |
| model_args.sliding_window is not None | |
| and model_args.sliding_window > 0 | |
| and ( | |
| hasattr(reference_model.decoder, "attention_type") | |
| and reference_model.decoder.attention_type == "sliding_attention" | |
| ) | |
| ): | |
| attn_mask += torch.tril( | |
| torch.full((max_seq_len, max_seq_len), -float("inf")), diagonal=-model_args.sliding_window | |
| ) | |
| ref_output = reference_model( | |
| pt_decode_input, | |
| positions[0], | |
| freqs_cis_i, | |
| mask=attn_mask, | |
| ) | |
| if ref_output.dim() == 2: | |
| ref_output = ref_output.unsqueeze(0) | |
| # Run TT model | |
| tt_out = tt_model( | |
| decode_input, | |
| None, | |
| rot_mats_global=rot_mats, | |
| rot_mats_local=rot_mats_local, | |
| user_id=0, | |
| mode=Mode.PREFILL, | |
| page_table=page_table_tt, | |
| ) | |
| tt_out = ttnn.to_torch( | |
| tt_out, | |
| mesh_composer=ttnn.ConcatMesh2dToTensor(mesh_device, dims=(1, 3), mesh_shape=model_args.cluster_shape), | |
| ) | |
| tt_output_torch = tt_out[:, 0:1, :, : model_args.dim].view( | |
| batch_size, max_seq_len, -1 | |
| ) # [ batch_size, seq, hidden_dim] | |
| passing, pcc_message = comp_pcc(ref_output, tt_output_torch) | |
| logger.info(comp_allclose(ref_output, tt_output_torch)) | |
| logger.info(f"PCC: {pcc_message}") | |
| if passing: | |
| logger.info("Decoder Block Passed!") | |
| else: | |
| logger.warning("Decoder Block Failed!") | |
| all_tests_pass = False | |
| if all_tests_pass: | |
| logger.info(f"All decode iterations Passed!") | |
| else: | |
| logger.warning("One or more iterations of decode Failed!") | |
| assert all_tests_pass, f"PCC value is lower than {0.99} for some of the outputs. Check Warnings!" | |