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

Меня зовут Георгий Гашокин, я программирую с 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 и других мощных технологий будущего.

Комментарии (11)


  1. exTvr
    05.09.2024 18:44
    +2

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

    Нет и нет.

    GPT - это инструмент, а не технология.

    /тут ещё бурчание про ножи, технологию их производства и применение их в других технологических цепочках, ну например, в общепите/на моей кухне/убить всех неверных/


    1. gogapro Автор
      05.09.2024 18:44

      в заключении я так и написал...


  1. Rorg
    05.09.2024 18:44
    +4

    Простите, но заголовок не раскрыт вообще, а от статьи можно было оставить только последний абзац (да и то толку не особо).

    а также обсудим этические вопросы, связанные с использованием подобных технологий.

    Я наверно пропустил, но где эта часть статьи?


    1. gogapro Автор
      05.09.2024 18:44

      начал расписывать но потом понял что факты о которых пишу нарушают целую серию Российских законов, вот и пришлось лаконично обобщить, я думаю вы и сами сможете догадаться в каких сферах сегодня используют эту технологию, сейчас новые "дизайнерские" наркотики в даркнете создают с помощью неё и многое другое...


      1. Rorg
        05.09.2024 18:44

        Тогда в чем смысл статьи, если:

        факты о которых пишу нарушают целую серию Российских законов

        ?


        1. gogapro Автор
          05.09.2024 18:44

          дать людям мой код на python для самостоятельного изучения этой архитектуры нейронной сети, когда я начинал изучать эту тему то не мог найти код в интернете чтоб попробовать, OpenAI не дает исходный код, другие пишут аналог на языке C, я прошел большой путь чтоб собрать по крупицам информацию и сделать свою модель, но решил ещё и предостеречь людей от глупостей... А вы почему то, место того чтобы дать оценку самому коду и проделанной работе, придираетесь к названию статьи и наполненности..


          1. Rorg
            05.09.2024 18:44

            Отлично. Назовите статью на манер "Как запустить GPT дома на python" и ни у кого не будет вопросов.

            Ваше текущее название предполагает что в статье будут рассмотрены этический вопросы связанные с обучением GPT (на пример надо или не надо платить авторам материалов, на которых обучали), как повлияло появление GPT на исследования, были ли совершены какие-либо прорывы. Появились ли новые виды мошенничества или преступлений вообще, связанные с использованием GPT. Возможно GPT помог правохранительным органам в чем-то. На крайний случай, какие курьезы случались в связи с использованием GPT (например тот случай, если я правильно помню, когда судья оштрафовала адвокатов за использование аргументов подготовленных GPT).

            Часть читателей (я например) зашли в статью "купившись" на громкий заголовок. Но ваша статья возможно и хорошая, но содержимое статьи и ее заголовок "живут" в разных вселенных.


  1. kozlov_de
    05.09.2024 18:44

    Мало нейронов.

    У нас больше


    1. gogapro Автор
      05.09.2024 18:44

      я специально сделал настройки такие в коде чтоб вы могли увеличивать количество нейронов сколько захотите, только вряд ли у вашей видеокарты будет столько памяти чтоб всё загрузить...


  1. kvd264
    05.09.2024 18:44

    Статья явно написана с помощью GPT. Последние абзацы этим прямо благоухают, как и структура всего текста в целом.


    1. gogapro Автор
      05.09.2024 18:44

      компания microsoft с недавних пор перестала брать на работу программистов и сотрудников которые не пользуются GPT в работе, так как работа с ней делается быстрее и качественнее... код и статью написал я сам а нейронку попросил исправить возможные ошибки и знаки... не вижу в этом нечего плохого, не любите использовать полезные инструменты тогда выкиньте отвертку и закручивайте болты ногтями....