Любую новую мощную технологию люди применяли как в добре, так и в злом умысле: когда изобрели порох, некоторые из него делали фейерверки и салюты, а другие оружие и бомбы, когда научились расщеплять атом, стали делать дешёвое электричество и бомбы, способные уничтожать города и страны. Технология, о которой я расскажу вам в этой статье, может изобрести новые лекарства без побочек, распознавать болезни раньше любыхдокторов, писать интересные книги и помочь человечеству решить множество проблем, но так же она может (не в тех руках) создать опасные вещества, создавать компьютерные вирусы, манипулировать людьми и многое другое…. Но ящик «пандоры» уже открыт и многие компании и обычные люди в мире уже обладают данной технологией, моя задача, упростить понимание о сием чуде) Надеюсь, вы будете использовать полученные знания только для блага!
Меня зовут Георгий Гашокин, я программирую с 7-и лет…
В мире стремительно развивающихся технологий, больших данных и искусственного интеллекта, модели, подобные GPT, занимают особое место. Они способны генерировать текст, переводить языки, писать различные виды творческого контента и отвечать на ваши вопросы информативно. Но как и любой мощный инструмент, GPT может быть использован как во благо, так и во зло.
В этой статье мы разберем мой код, который демонстрирует создание и обучение упрощенной версии GPT модели, а также обсудим этические вопросы, связанные с использованием подобных технологий.
Ближе к делу:
Часть 1: Загрузка и обработка данных
import time import joblib import pandas as pd import tensorflow as tf # 2.5.2 from tensorflow.keras.layers import Input, Dense, Dropout, BatchNormalization, ActivityRegularization, Embedding from tensorflow.keras.models import Model from tensorflow.keras.optimizers import Adam from tensorflow.keras.preprocessing.text import Tokenizer from tensorflow.keras.preprocessing.sequence import pad_sequences import numpy as np from tensorflow.python.keras.callbacks import ReduceLROnPlateau, LearningRateScheduler, EarlyStopping, ModelCheckpoint from tensorflow.python.keras.layers import TimeDistributed import tensorflow_datasets as tfds from tensorflow_addons.optimizers import LAMB from tensorflow.keras.regularizers import l1, l2 from transformers import AutoTokenizer from tensorflow.keras.models import load_model # Загрузка данных with open("vopros_otvet.txt", "r", encoding="utf-8") as file: data = file.read() in_text_max = 128 # Максимальная длина входной последовательности out_text_max = 300 # Максимальная длина генерируемого текста # параметры модели gpt3 gpt4 embedding_dim = 16 # 768 # 2048 (Размерность векторов эмбеддингов) num_heads = 3 # 12 # 64 (Количество голов внимания в MultiHeadAttention) dense_dim = 8 # 3072 # 4096 (Количество нейронов в Dense слоях) num_layers = 3 # 96 # 96 (Количество слоев Transformer) dropout = 0.3 # 0.3 (Вероятность dropout) train_text_but = 1 # Флаг для обучения модели (1 - обучать, 0 - не обучать) generate_text_but = 1 # Флаг для генерации текста (1 - генерировать, 0 - не генерировать)
content_copyUse code with caution.Python
В этом блоке кода мы импортируем необходимые библиотеки, загружаем данные из файла и определяем основные параметры модели. Я написал рядом с параметрами модели те параметры которые с большой вероятностью есть в реальной GPT-3 и GPT-4. Если у вас мало VRAM то ставьте параметры меньше чтобы модель могла загрузиться вся в память видеокарты, может быть в другой статье я сделаю другую модель которая будет загружаться только в оперативку….
Что касается файла vopros_otvet.txt этот файл нужен для обучения модели в нем я сохранил набор вопросов и ответов вида:
привет! <VOP> Здравствуйте! Чем я могу Вам помочь? <END> Какой калибр АК предпочтительнее 5,45 или 7,62? <VOP> Как и в любом выборе, ответ на этот вопрос зависит от конкретных обстоятельств и задач, которые нужно решить. Калибр 5,45 мм был разработан в СССР в 1970-х годах как ответ на американский калибр 5,56 мм, который использовался в штурмовых винтовках M16. 5,45 мм позволяет снизить отдачу и повысить точность стрельбы на дальних дистанциях, что делает его предпочтительным для стрельбы на больших расстояниях. Кроме того, патроны 5,45 мм легче и компактнее, что позволяет носить больше боеприпасов. Калибр 7,62 мм является более традиционным для автоматического оружия и используется в АК-47 и АКМ. Он имеет большую остановочную силу и может пробивать бронежилеты и стены, что делает его предпочтительным для боевых условий и стрельбы на ближних дистанциях. Таким образом, если нужно стрелять на больших расстояниях и повышать точность, то предпочтительнее калибр 5,45 мм. Если же нужно пробивать бронежилеты и стены, то лучше выбрать калибр 7,62 мм. В любом случае, выбор калибра должен быть обоснован и зависеть от конкретных задач и условий. <END>
Заметьте что вопрос заканчивается <VOP> а ответ заканчивается <END> это важно так как нейронная сеть будет понимать что после <VOP> нужно генерировать ответ и как только вы увидите что нейронка после генерации текста написала <END> значит она закончила мысль и пора её тормозить, иначе продолжит генерировать бред…
Часть 2: Токенизация
Токенизатор — это инструмент обработки текста, который разделяет текст на отдельные элементы, называемые токенами. Коротко говоря, токенизатор просмотрит весь текст в файле vopros_otvet.txt разобьет его на простые повторяющиеся части типа приставки, суффиксы, корни в словах, отдельные буквы и знаки, и даст каждому токену цифровой номер, так нейронной сети будет легче работать с текстом, так как она понимает только цифры
# Токенизация special_tokens = ["<START>", "<END>","<VOP>","<сrypto-15:>"] # Специальные токены oov_token = "<OOV>" # Токен для слов, не встречающихся в словаре tokenizer = Tokenizer(lower=False, # Не приводить к нижнему регистру split = ' ', # Разделитель - пробел filters = '', # Не фильтровать символы oov_token=oov_token, # Токен для неизвестных слов #char_level=True # Не использовать символьную токенизацию ) tokenizer.fit_on_texts(data.split('\n')) # Обучение токенизатора на данных # Добавление специальных токенов в word_index tokenizer.word_index.update({tok: idx+len(tokenizer.word_index) for idx, tok in enumerate(special_tokens)}) # Изменение количества слов в word_counts for tok in special_tokens: tokenizer.word_counts[tok] = 1 # Обновление количества слов tokenizer.num_words = len(tokenizer.word_index) + 1 joblib.dump(tokenizer,'tokenizer.joblib') # Сохранение токенизатора total_words = len(tokenizer.word_index) + 1 # Общее количество слов в словаре print(tokenizer.word_index) # Вывод словаря токенизатора print(total_words) # Вывод общего количества слов
content_copyUse code with caution.Python
Описание:
В этом блоке кода мы создаем токенизатор Tokenizer и обучаем его на наших данных.
-
special_tokens — это список специальных токенов, которые будут добавлены в словарь.
-
oov_token — это токен, который будет использоваться для слов, не встречающихся в словаре.
-
Tokenizer — это класс из библиотеки keras.preprocessing.text, который используется для токенизации текста.
-
fit_on_texts — это метод класса Tokenizer, который используется для обучения токенизатора на данных.
-
word_index — это словарь, который сопоставляет слова с их числовыми индексами.
-
word_counts — это словарь, который сопоставляет слова с их частотой встречаемости в данных.
-
num_words — это общее количество слов в словаре.
-
joblib.dump — это функция, которая используется для сохранения токенизатора в файл.
Часть 3: Подготовка данных для обучения
input_sequences = [] for line in data.split("\n"): token_list = tokenizer.texts_to_sequences([line])[0] # Преобразование текста в числовую последовательность for i in range(1, len(token_list)): n_gram_sequence = token_list[: i + 1] # Создание n-грамм input_sequences.append(n_gram_sequence) max_sequence_len = in_text_max input_sequences = np.array(pad_sequences(input_sequences, maxlen=max_sequence_len, padding="pre")) # Дополнение последовательностей нулями # Разделение на x и y data = [] xs, labels = input_sequences[:, :-1], input_sequences[:, -1] # Разделение на входные данные и метки input_sequences = [] ys = tf.keras.utils.to_categorical(labels, num_classes=total_words) # Преобразование меток в one-hot кодировку
content_copyUse code with caution.Python
Этот блок кода отвечает за подготовку данных для обучения модели.
-
texts_to_sequences — метод токенизатора, который преобразует текст в числовую последовательность.
-
n-граммы — это последовательности из n слов.
-
pad_sequences — функция из библиотеки keras.preprocessing.sequence, которая используется для дополнения последовательностей нулями до заданной длины.
-
xs — это массив входных данных.
-
labels — это массив меток.
-
to_categorical — функция из библиотеки keras.utils, которая используется для преобразования меток в one-hot кодировку.
Часть 4: Создание и компиляция модели
if train_text_but == 1: # Создание модели print(max_sequence_len-1) input_layer = Input(shape=(max_sequence_len-1,)) # Входной слой embedding_layer = tf.keras.layers.Embedding(total_words, embedding_dim)(input_layer) # Слой эмбеддингов for i in range(num_layers): transformer_layer = tf.keras.layers.MultiHeadAttention(num_heads=num_heads, key_dim=embedding_dim)(embedding_layer, embedding_layer) # Слой MultiHeadAttention transformer_layer = tf.keras.layers.BatchNormalization()(transformer_layer) # Слой BatchNormalization transformer_layer = tf.keras.layers.Dropout(dropout)(transformer_layer) # Слой Dropout transformer_layer = tf.keras.layers.ActivityRegularization(l1=0.001, l2=0.001)(transformer_layer) # Слой ActivityRegularization dense_layer = tf.keras.layers.Dense(dense_dim, activation='relu')(transformer_layer) # Слой Dense dropout_layer = tf.keras.layers.Dropout(dropout)(dense_layer) # Слой Dropout flatten_layer = tf.keras.layers.Flatten()(dropout_layer) # Слой Flatten output_layer = tf.keras.layers.Dense(total_words, activation='softmax')(flatten_layer) # Выходной слой model = Model(inputs=input_layer, outputs=output_layer) # Создание модели # Компиляция модели optimizer = LAMB(learning_rate=0.001) # Оптимизатор LAMB model.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=['accuracy']) # Компиляция модели model.summary() # Вывод информации о модели
content_copyUse code with caution.Python
Здесь мы создаем модель на основе MultiHeadAttention слоев и компилируем ее с использованием оптимизатора LAMB.
Часть 5: Обучение модели
reduce_lr = ReduceLROnPlateau(monitor='loss', factor=0.98, patience=3, min_lr=0.0000001, verbose=1 ) # Callback для уменьшения learning rate checkpointer = ModelCheckpoint( filepath="checkpointer.ckpt", monitor='loss', verbose=1, save_weights_only=True) # Callback для сохранения весов модели call_acc = tf.keras.callbacks.ModelCheckpoint( filepath='testing_accuracy.ckpt', monitor='accuracy', verbose=1, save_best_only=True,mode='max') # Callback для сохранения модели с лучшей точностью call_loss = tf.keras.callbacks.ModelCheckpoint( filepath='testing_loss.ckpt', monitor='loss', verbose=1, save_best_only=True,mode='min') # Callback для сохранения модели с наименьшей потерей early_stopping = EarlyStopping(monitor='loss', patience=50, restore_best_weights=True) # Callback для остановки обучения при отсутствии улучшения def schedule(epoch, lr): if epoch % 1 == 0: print('lr- ',round(lr,8)) if lr > 0.000001: lr = lr * 0.995 return lr lr_scheduler = LearningRateScheduler(schedule) # Callback для изменения learning rate по расписанию # Обучение модели model.fit(xs, ys, epochs=100, verbose=1, batch_size=32, callbacks=[ lr_scheduler, reduce_lr, early_stopping, ], shuffle=True) # Обучение модели model.save('GPT-3-my.h5') # Сохранение модели model.save_weights('model_weights_part_{}.h5'.format(1)) # Сохранение весов модели
content_copyUse code with caution.Python
Описание:
Этот блок кода отвечает за обучение модели.
-
ReduceLROnPlateau — это callback, который уменьшает learning rate, если значение monitored quantity перестало улучшаться.
-
ModelCheckpoint — это callback, который сохраняет веса модели.
-
EarlyStopping — это callback, который останавливает обучение, если значение monitored quantity перестало улучшаться.
-
LearningRateScheduler — это callback, который изменяет learning rate по расписанию.
-
fit — это метод класса Model, который используется для обучения модели.
-
epochs — это количество эпох обучения.
-
verbose — это уровень детализации вывода информации во время обучения.
-
batch_size — это размер батча.
-
callbacks — это список callback-функций.
-
shuffle — это флаг, который указывает, нужно ли перемешивать данные перед каждой эпохой.
-
save — это метод класса Model, который используется для сохранения модели.
-
save_weights — это метод класса Model, который используется для сохранения весов модели.
Часть 6: Генерация текста
if generate_text_but == 1: model = load_model('GPT-3-my.h5') # Загрузка модели tokenizer = joblib.load('tokenizer.joblib') # Загрузка токенизатора # Генерация текста def generate_text(seed_text, next_words, model, max_sequence_len): for _ in range(next_words): token_list = tokenizer.texts_to_sequences([seed_text])[0] # Преобразование текста в числовую последовательность token_list = pad_sequences([token_list], maxlen=max_sequence_len - 1, padding='pre') # Дополнение последовательности нулями predicted = model.predict(token_list, verbose=0) # Предсказание следующего слова output_word = "" for word, index in tokenizer.word_index.items(): if index == np.argmax(predicted): # Поиск слова с наибольшей вероятностью output_word = word print(output_word) break seed_text += " " + output_word # Добавление предсказанного слова к тексту # time.sleep(1) return seed_text.title() # Возврат сгенерированного текста text_in = 'Как сделать LSD? ' # Начальный текст generated_text = generate_text(text_in, out_text_max, model, max_sequence_len) # Генерация текста print(generated_text) # Вывод сгенерированного текста
content_copyUse code with caution.Python
Здесь мы загружаем обученную модель и токенизатор, а затем генерируем текст на основе заданного начального текста.
Описание:
Этот блок кода отвечает за генерацию текста.
-
load_model — это функция из библиотеки keras.models, которая используется для загрузки модели.
-
generate_text — это функция, которая генерирует текст.
-
seed_text — это начальный текст.
-
next_words — это количество слов, которые нужно сгенерировать.
-
predict — это метод класса Model, который используется для предсказания.
-
argmax — это функция из библиотеки numpy, которая возвращает индекс максимального элемента в массиве.
GPT: Добро и Зло
После разбора кода давайте вернемся к этическим вопросам. Как уже было сказано, GPT и подобные модели обладают огромным потенциалом как для благих целей (образование, медицина, наука, искусство), так и для негативных (дезинформация, мошенничество, кибербуллинг, плагиат).
Заключение
GPT — это мощный инструмент, и его влияние на мир зависит от того, как мы его используем. Важно помнить об этических аспектах разработки и применения искусственного интеллекта и стремиться к ответственному использованию таких технологий, как GPT.
Вопросы для обсуждения:
-
Какие еще примеры использования GPT в добрых и злых целях вы можете привести?
-
Как можно предотвратить злоупотребление GPT и подобными технологиями?
-
Какова роль этики в развитии и применении искусственного интеллекта?
Давайте вместе обсудим эти важные вопросы и найдем пути к ответственному использованию GPT и других мощных технологий будущего.
ссылка на оригинал статьи https://habr.com/ru/articles/841212/
Добавить комментарий