from transformers import AutoModelForCausalLM, AutoTokenizerChapter 2 - Tokens and Token Embeddings
Downloading and Running An LLM
The first step is to load our model onto the GPU for faster inference. Note that we load the model and tokenizer separately and keep them as such so that we can explore them separately.
# Load model and tokenizer
model = AutoModelForCausalLM.from_pretrained(
"microsoft/Phi-3-mini-4k-instruct",
device_map="cuda",
torch_dtype="auto",
trust_remote_code=False,
attn_implementation="flash_attention_2",
)
tokenizer = AutoTokenizer.from_pretrained("microsoft/Phi-3-mini-4k-instruct")`torch_dtype` is deprecated! Use `dtype` instead!
prompt = "Write an email apologizing to Sarah for the tragic gardening mishap. Explain how it happened.<|assistant|>"
# Tokenize the input prompt
input_ids = tokenizer(prompt, return_tensors="pt").input_ids.to("cuda")
# Generate the text
generation_output = model.generate(
input_ids=input_ids,
max_new_tokens=50,
)
# Print the output
print(tokenizer.decode(generation_output[0]))The attention mask is not set and cannot be inferred from input because pad token is same as eos token. As a consequence, you may observe unexpected behavior. Please pass your input's `attention_mask` to obtain reliable results.
Write an email apologizing to Sarah for the tragic gardening mishap. Explain how it happened.<|assistant|> Subject: Sincere Apologies for the Gardening Mishap
Dear Sarah,
I hope this message finds you well. I am writing to express my deepest apologies for the unfortunate incident that
print(input_ids)tensor([[14350, 385, 4876, 27746, 5281, 304, 19235, 363, 278, 25305,
293, 16423, 292, 286, 728, 481, 29889, 12027, 7420, 920,
372, 9559, 29889, 32001]], device='cuda:0')
for id in input_ids[0]:
print(tokenizer.decode(id))Write
an
email
apolog
izing
to
Sarah
for
the
trag
ic
garden
ing
m
ish
ap
.
Exp
lain
how
it
happened
.
<|assistant|>
generation_outputtensor([[14350, 385, 4876, 27746, 5281, 304, 19235, 363, 278, 25305,
293, 16423, 292, 286, 728, 481, 29889, 12027, 7420, 920,
372, 9559, 29889, 32001, 3323, 622, 29901, 317, 3742, 406,
6225, 11763, 363, 278, 19906, 292, 341, 728, 481, 13,
13, 13, 29928, 799, 19235, 29892, 13, 13, 13, 29902,
4966, 445, 2643, 14061, 366, 1532, 29889, 306, 626, 5007,
304, 4653, 590, 6483, 342, 3095, 11763, 363, 278, 443,
6477, 403, 15134, 393]], device='cuda:0')
print(tokenizer.decode(3323))
print(tokenizer.decode(622))
print(tokenizer.decode([3323, 622]))
print(tokenizer.decode(29901))Sub
ject
Subject
:
Comparing Trained LLM Tokenizers
from transformers import AutoModelForCausalLM, AutoTokenizer
colors_list = [
'102;194;165', '252;141;98', '141;160;203',
'231;138;195', '166;216;84', '255;217;47'
]
def show_tokens(sentence, tokenizer_name):
tokenizer = AutoTokenizer.from_pretrained(tokenizer_name)
token_ids = tokenizer(sentence).input_ids
for idx, t in enumerate(token_ids):
print(
f'\x1b[0;30;48;2;{colors_list[idx % len(colors_list)]}m' +
tokenizer.decode(t) +
'\x1b[0m',
end=' '
)text = """
English and CAPITALIZATION
🎵 鸟
show_tokens False None elif == >= else: two tabs:" " Three tabs: " "
12.0*50=600
"""show_tokens(text, "bert-base-uncased")[CLS] english and capital ##ization [UNK] [UNK] show _ token ##s false none eli ##f = = > = else : two tab ##s : " " three tab ##s : " " 12 . 0 * 50 = 600 [SEP]
show_tokens(text, "bert-base-cased")[CLS] English and CA ##PI ##TA ##L ##I ##Z ##AT ##ION [UNK] [UNK] show _ token ##s F ##als ##e None el ##if = = > = else : two ta ##bs : " " Three ta ##bs : " " 12 . 0 * 50 = 600 [SEP]
show_tokens(text, "gpt2")
English and CAP ITAL IZ ATION
� � � � � �
show _ t ok ens False None el if == >= else : two tabs :" " Three tabs : " "
12 . 0 * 50 = 600
show_tokens(text, "google/flan-t5-small")English and CA PI TAL IZ ATION <unk> <unk> show _ to ken s Fal s e None e l if = = > = else : two tab s : " " Three tab s : " " 12. 0 * 50 = 600 </s>
# The official is `tiktoken` but this the same tokenizer on the HF platform
show_tokens(text, "Xenova/gpt-4")
English and CAPITAL IZATION
� � � � � �
show _tokens False None elif == >= else : two tabs :" " Three tabs : " "
12 . 0 * 50 = 600
# You need to request access before being able to use this tokenizer
show_tokens(text, "bigcode/starcoder2-15b")
English and CAPITAL IZATION
� � � � �
show _ tokens False None elif == >= else : two tabs :" " Three tabs : " "
1 2 . 0 * 5 0 = 6 0 0
show_tokens(text, "facebook/galactica-1.3b")
English and CAP ITAL IZATION
� � � � � � �
show _ tokens False None elif == > = else : two t abs : " " Three t abs : " "
1 2 . 0 * 5 0 = 6 0 0
show_tokens(text, "microsoft/Phi-3-mini-4k-instruct")
English and C AP IT AL IZ ATION
� � � � � � �
show _ to kens False None elif == >= else : two tabs :" " Three tabs : " "
1 2 . 0 * 5 0 = 6 0 0
Contextualized Word Embeddings From a Language Model (Like BERT)
from transformers import AutoModel, AutoTokenizer
# Load a tokenizer
tokenizer = AutoTokenizer.from_pretrained("microsoft/deberta-base")
# Load a language model
model = AutoModel.from_pretrained("microsoft/deberta-v3-xsmall")
# Tokenize the sentence
tokens = tokenizer('Hello world', return_tensors='pt')
# Process the tokens
output = model(**tokens)[0]output.shapetorch.Size([1, 4, 384])
for token in tokens['input_ids'][0]:
print(tokenizer.decode(token))[CLS]
Hello
world
[SEP]
outputtensor([[[-3.4816, 0.0861, -0.1819, ..., -0.0612, -0.3911, 0.3017],
[ 0.1898, 0.3208, -0.2315, ..., 0.3714, 0.2478, 0.8048],
[ 0.2071, 0.5036, -0.0485, ..., 1.2175, -0.2292, 0.8582],
[-3.4278, 0.0645, -0.1427, ..., 0.0658, -0.4367, 0.3834]]],
grad_fn=<NativeLayerNormBackward0>)
Text Embeddings (For Sentences and Whole Documents)
from sentence_transformers import SentenceTransformer
# Load model
model = SentenceTransformer('sentence-transformers/all-mpnet-base-v2')
# Convert text to text embeddings
vector = model.encode("Best movie ever!")vector.shape(768,)
Word Embeddings Beyond LLMs
import gensim.downloader as api
# Download embeddings (66MB, glove, trained on wikipedia, vector size: 50)
# Other options include "word2vec-google-news-300"
# More options at https://github.com/RaRe-Technologies/gensim-data
model = api.load("glove-wiki-gigaword-50")[==================================================] 100.0% 66.0/66.0MB downloaded
model.most_similar([model['king']], topn=11)[('king', 1.0000001192092896),
('prince', 0.8236179351806641),
('queen', 0.7839043140411377),
('ii', 0.7746230363845825),
('emperor', 0.7736247777938843),
('son', 0.766719400882721),
('uncle', 0.7627150416374207),
('kingdom', 0.7542161345481873),
('throne', 0.7539914846420288),
('brother', 0.7492411136627197),
('ruler', 0.7434253692626953)]
model.most_similar([model['queen']], topn=11)[('queen', 1.0000001192092896),
('princess', 0.8515166640281677),
('lady', 0.8050609230995178),
('elizabeth', 0.7873042225837708),
('king', 0.7839043140411377),
('prince', 0.7821861505508423),
('coronation', 0.769277811050415),
('consort', 0.7626097202301025),
('royal', 0.7442865371704102),
('crown', 0.7382649183273315),
('victoria', 0.728577196598053)]
Recommending songs by embeddings
import pandas as pd
from urllib import request
# Get the playlist dataset file
data = request.urlopen('https://storage.googleapis.com/maps-premium/dataset/yes_complete/train.txt')
# Parse the playlist dataset file. Skip the first two lines as
# they only contain metadata
lines = data.read().decode("utf-8").split('\n')[2:]
# Remove playlists with only one song
playlists = [s.rstrip().split() for s in lines if len(s.split()) > 1]
# Load song metadata
songs_file = request.urlopen('https://storage.googleapis.com/maps-premium/dataset/yes_complete/song_hash.txt')
songs_file = songs_file.read().decode("utf-8").split('\n')
songs = [s.rstrip().split('\t') for s in songs_file]
songs_df = pd.DataFrame(data=songs, columns = ['id', 'title', 'artist'])
songs_df = songs_df.set_index('id')songs_df.to_csv('chen_recs_songs.csv')print( 'Playlist #1:\n ', playlists[0], '\n')
print( 'Playlist #2:\n ', playlists[1])Playlist #1:
['0', '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', '2', '42', '43', '44', '45', '46', '47', '48', '20', '49', '8', '50', '51', '52', '53', '54', '55', '56', '57', '25', '58', '59', '60', '61', '62', '3', '63', '64', '65', '66', '46', '47', '67', '2', '48', '68', '69', '70', '57', '50', '71', '72', '53', '73', '25', '74', '59', '20', '46', '75', '76', '77', '59', '20', '43']
Playlist #2:
['78', '79', '80', '3', '62', '81', '14', '82', '48', '83', '84', '17', '85', '86', '87', '88', '74', '89', '90', '91', '4', '73', '62', '92', '17', '53', '59', '93', '94', '51', '50', '27', '95', '48', '96', '97', '98', '99', '100', '57', '101', '102', '25', '103', '3', '104', '105', '106', '107', '47', '108', '109', '110', '111', '112', '113', '25', '63', '62', '114', '115', '84', '116', '117', '118', '119', '120', '121', '122', '123', '50', '70', '71', '124', '17', '85', '14', '82', '48', '125', '47', '46', '72', '53', '25', '73', '4', '126', '59', '74', '20', '43', '127', '128', '129', '13', '82', '48', '130', '131', '132', '133', '134', '135', '136', '137', '59', '46', '138', '43', '20', '139', '140', '73', '57', '70', '141', '3', '1', '74', '142', '143', '144', '145', '48', '13', '25', '146', '50', '147', '126', '59', '20', '148', '149', '150', '151', '152', '56', '153', '154', '155', '156', '157', '158', '159', '160', '161', '162', '163', '164', '165', '166', '167', '168', '169', '170', '171', '172', '173', '174', '175', '60', '176', '51', '177', '178', '179', '180', '181', '182', '183', '184', '185', '57', '186', '187', '188', '189', '190', '191', '46', '192', '193', '194', '195', '196', '197', '198', '25', '199', '200', '49', '201', '100', '202', '203', '204', '205', '206', '207', '32', '208', '209', '210']
from gensim.models import Word2Vec
# Train our Word2Vec model
model = Word2Vec(
playlists, vector_size=32, window=20, negative=50, min_count=1, workers=4
)song_id = 2172
# Ask the model for songs similar to song #2172
model.wv.most_similar(positive=str(song_id))[('3094', 0.9984354972839355),
('3167', 0.997356653213501),
('10105', 0.9970279335975647),
('3126', 0.9969783425331116),
('2976', 0.9967626333236694),
('3116', 0.9966928362846375),
('10084', 0.9965797066688538),
('6624', 0.9957831501960754),
('2704', 0.995732843875885),
('6658', 0.9954785108566284)]
print(songs_df.iloc[2172])title Fade To Black
artist Metallica
Name: 2172 , dtype: object
import numpy as np
def print_recommendations(song_id):
similar_songs = np.array(
model.wv.most_similar(positive=str(song_id),topn=5)
)[:,0]
return songs_df.iloc[similar_songs]
# Extract recommendations
print_recommendations(2172)| title | artist | |
|---|---|---|
| id | ||
| 3094 | Breaking The Law | Judas Priest |
| 3167 | Unchained | Van Halen |
| 10105 | Three Lock Box | Sammy Hagar |
| 3126 | Heavy Metal | Sammy Hagar |
| 2976 | I Don't Know | Ozzy Osbourne |
print_recommendations(2172)| title | artist | |
|---|---|---|
| id | ||
| 3094 | Breaking The Law | Judas Priest |
| 3167 | Unchained | Van Halen |
| 10105 | Three Lock Box | Sammy Hagar |
| 3126 | Heavy Metal | Sammy Hagar |
| 2976 | I Don't Know | Ozzy Osbourne |
print_recommendations(842)| title | artist | |
|---|---|---|
| id | ||
| 27081 | Give Me Everything (w\/ Ne-Yo, Afrojack & Nayer) | Pitbull |
| 413 | If I Ruled The World (Imagine That) (w\/ Laury... | Nas |
| 18844 | Murder She Wrote | Chaka Demus & Pliers |
| 211 | Hypnotize | The Notorious B.I.G. |
| 34678 | Run De Riddim | 3 Canal |