Repository navigation
Expand file tree
/
Copy pathnumerical_tests_example.py
More file actions
167 lines (123 loc) · 4.81 KB
/
Copy pathnumerical_tests_example.py
File metadata and controls
167 lines (123 loc) · 4.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree.
import logging
import torch
import torch.distributed.checkpoint as dcp
import torch.nn.functional as F
from torchtitan.components.checkpointer import ModelWrapper
from torchtitan.config import ConfigLoader
from torchtitan.observability.logging import init_logger
from transformers import AutoModelForCausalLM
logger = logging.getLogger(__name__)
device_type = "cuda" if torch.cuda.is_available() else "cpu"
def loss_fn(logits1, logits2):
# Convert logits to probabilities
probs1 = F.log_softmax(logits1, dim=-1)
probs2 = F.softmax(logits2, dim=-1)
# Calculate KL Divergence
kl_loss = F.kl_div(probs1, probs2, reduction="mean")
return kl_loss
@torch.no_grad
def forward_hf(model_name, model_path: str | None, input_ids):
# Load the tokenizer and model
model_path = model_path if model_path else model_name
model = AutoModelForCausalLM.from_pretrained(model_path)
device = torch.device(device_type)
model.to(device)
# List to store outputs
outputs_list = []
for inputs in input_ids:
inputs = inputs.to(device)
outputs = model.generate(
inputs=inputs,
max_length=prompt_len + 1,
do_sample=False,
output_logits=True,
return_dict_in_generate=True,
)
outputs = torch.stack(outputs.logits)
outputs_list.append(outputs)
del model
torch.cuda.empty_cache()
return outputs_list
@torch.no_grad
def forward_tt(model_name, config_name, checkpoint_path, test_set):
config = ConfigLoader().load(["--module", model_name, "--config", config_name])
model_config = config.model # pyrefly: ignore [missing-attribute]
model = model_config.build()
# materalize model
device = torch.device(device_type)
model.to_empty(device=device)
model.init_weights(buffer_device=device)
model.eval()
modelWrapper = ModelWrapper(model)
state_dict = modelWrapper._get_state_dict()
# Checkpoint Loading
logger.info(f"Loading checkpoint at: {checkpoint_path}")
dcp.load(state_dict, checkpoint_id=checkpoint_path)
output_list = []
for prompt in test_set:
input_ids = prompt.to(device_type)
# ensure batch dimension (T,) --> (B, T)
if input_ids.ndim == 1:
input_ids = input_ids.unsqueeze(0)
# obtains the logits of only the last token in the predictions
predictions = model(input_ids)[:, -1, :].unsqueeze(1)
output_list.append(predictions)
del model
torch.cuda.empty_cache()
return output_list
if __name__ == "__main__":
init_logger()
# hf params
hf_model_name = "meta-llama/Meta-Llama-3-8B"
# tt params
model_name = "llama3"
config_name = "llama3_8b"
checkpoint_path = "outputs/test_checkpoint/step-0-fromhf" # dcp checkpoint from convert_from_hf.py
# dcp checkpoint from convert_from_hf.py without using sd_adapter's permute
checkpoint_path_no_perm = "outputs/test_checkpoint/step-0-fromhfnoperm"
# test params
prompt_len = 8
test_size = 100
config = ConfigLoader().load(["--module", model_name, "--config", config_name])
from torchtitan.components.tokenizer import HuggingFaceTokenizer
# pyrefly: ignore [missing-argument, missing-attribute]
tokenizer = HuggingFaceTokenizer(config.hf_assets_path)
# Build test set of randomly generated token ids
test_set = [
torch.randint(
0,
tokenizer.get_vocab_size(),
(
1, # batch size
prompt_len,
),
)
for _ in range(test_size)
]
# baseline logits
baseline_hf_outputs = forward_hf(hf_model_name, None, test_set)
# testing from hf conversion
from_hf_outputs = forward_tt(model_name, config_name, checkpoint_path, test_set)
from_hf_outputs_no_perm = forward_tt(
model_name, config_name, checkpoint_path_no_perm, test_set
)
# Define the set of outputs to test loss for
test_configs = {
"from_hf": [baseline_hf_outputs, from_hf_outputs],
"from_hf_no_perm": [baseline_hf_outputs, from_hf_outputs_no_perm],
}
avg_losses = {}
for test_name, (baseline_outputs, conversion_outputs) in test_configs.items():
total_loss: int | torch.Tensor = 0
for baseline, outputs in zip(baseline_outputs, conversion_outputs):
total_loss += loss_fn(baseline, outputs)
avg_loss = total_loss / len(test_set)
# pyrefly: ignore [missing-attribute]
avg_losses[test_name] = avg_loss.item()
for test_name, avg_loss in avg_losses.items():
print(f"Average loss for test {test_name} is {avg_loss}")