GPT — технология добра/зла

от автора

Любую новую мощную технологию люди применяли как в добре, так и в злом умысле: когда изобрели порох, некоторые из него делали фейерверки и салюты, а другие оружие и бомбы, когда научились расщеплять атом, стали делать дешёвое электричество и бомбы, способные уничтожать города и страны. Технология, о которой я расскажу вам в этой статье, может изобрести новые лекарства без побочек, распознавать болезни раньше любыхдокторов, писать интересные книги и помочь человечеству решить множество проблем, но так же она может (не в тех руках) создать опасные вещества, создавать компьютерные вирусы, манипулировать людьми и многое другое…. Но ящик «пандоры» уже открыт и многие компании и обычные люди в мире уже обладают данной технологией, моя задача, упростить понимание о сием чуде) Надеюсь, вы будете использовать полученные знания только для блага!

Меня зовут Георгий Гашокин, я программирую с 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/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *