Отключить слои в модели GPT-2

В настоящее время я использую модель GPT-2, обученную немецким текстам. Я хотел бы сгенерировать следующее слово в тексте с учетом фрагмента контекста, но вместо того, чтобы использовать всю модель для предсказания следующего слова, я хочу, чтобы каждый из 12 слоев предсказывал следующее слово отдельно, поэтому я получаю 12 предсказаний для следующее слово. Другими словами, я хочу «повредить» все слои, кроме одного, чтобы они вообще не участвовали в предсказании следующего слова.

Это моя модель:

# import modules
from transformers import AutoTokenizer, AutoModelWithLMHead, AutoModelForCausalLM
import torch

# download pre-trained German GPT-2 model & tokenizer
tokenizer = AutoTokenizer.from_pretrained("dbmdz/german-gpt2")

# initialise the model
model = AutoModelForCausalLM.from_pretrained("dbmdz/german-gpt2", pad_token_id = tokenizer.eos_token_id)

А вот пример куска контекста:

input_text = "Orlando liebte von Natur aus einsame Orte, weite Ausblicke und das Gefühl, für immer und ewig" # correct next word: "allein"

Я подумал, может быть, я мог бы установить все веса внимания на 0 в слоях, которые я хочу исключить, но я понятия не имею, правильно ли это и как изменить веса в модели. Кто-нибудь знает, как это решить, и может объяснить, что мне нужно делать? Я никогда раньше не использовал GPT2, так что это меня очень сбивает с толку.

Заранее спасибо за вашу помощь / любые идеи!

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
61
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я не могу придумать хороший способ повредить, например. просто слой i и сохраните слои после него, так как весь вывод на слой i+1 проходит через слой i. Вместо этого вы можете увидеть, что модель до уровня я предсказал бы следующим образом:

Я бы создал новую модель, которая состоит из первых i слоев внимания, за которыми следует новый последний линейный слой с softmax (отражающий окончательный выходной слой исходной модели). Я бы переобучил (точно настроил) эту модель с замороженными весами исходных слоев внимания, и обучаются только веса нового линейного слоя. Если вы не знакомы с базовой архитектурой трансформатора, это хороший блог: https://jalammar.github.io/illustrated-transformer/. Вы можете заморозить слои, установив require_grad = False только для этих слоев при создании модели.

Спасибо за ответ, обязательно загляну в блог! Можно ли установить веса слоев, которые я хочу отключить, на 0, чтобы информация не обрабатывалась должным образом отключенными слоями, но модель оставалась нетронутой?

Merle 25.04.2023 17:25
Ответ принят как подходящий

Технически это возможно, но, вероятно, не даст вам ничего полезного для понимания вашей сети. Вы можете думать о такой сети как о вычислении y = слой (слой (... (слой (слой (x, тета [0]), тета [1]) ...), тета [n-2]), тета [n-1]), где тета [i] — веса i-го слоя. Установка весов для определенного слоя на 0 сделает входные данные для слоя i+1 мусором. Между слоями есть остаточные связи, поэтому, возможно, произойдет что-то не мусорное, но я бы не стал доверять этому.

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

from transformers import AutoTokenizer, AutoModelWithLMHead, AutoModelForCausalLM
import torch
import re

# download pre-trained German GPT-2 model & tokenizer
tokenizer = AutoTokenizer.from_pretrained("dbmdz/german-gpt2")

# initialise the model
model = AutoModelForCausalLM.from_pretrained("dbmdz/german-gpt2", pad_token_id = tokenizer.eos_token_id)

input_text = ["Orlando liebte von Natur aus einsame Orte, weite Ausblicke und das Gefühl, für immer und ewig", # correct next word: "allein"
              "Wo sich Fuchs und Hase gute Nacht", # correct next word sagen.
              ]
prompt = [torch.tensor(tokenizer.encode(s)).unsqueeze(0) for s in input_text]

ngenerate = 20

sample_output0 = [tokenizer.decode(model.generate(s,max_length=s.shape[-1]+ngenerate)[0,:]) for s in prompt]
print('\n***Before zeroing***')
for i,s in enumerate(sample_output0):
  print(f'{i}: {s}\n')

# zero-out layer 5

layeri = 5

# find weight names for this layer, will include the string 'transformer.h5.'
paramnames = filter(lambda s: re.search(f'transformer.h\.{layeri}\.',s) is not None,model.state_dict().keys())

# set these weights to 0
for paramname in paramnames:
  w = model.state_dict()[paramname]
  if w.ndim > 0:
    w[:] = 0

# generate some sample output
print('\n***After zeroing***')
sample_output1 = [tokenizer.decode(model.generate(s,max_length=s.shape[-1]+ngenerate)[0,:]) for s in prompt]
print('Before zeroing')
for i,s in enumerate(sample_output1):
  print(f'{i}: {s}\n')

Результат этого:

***Before zeroing***
0: Orlando liebte von Natur aus einsame Orte, weite Ausblicke und das Gefühl, für immer und ewig in der Nähe zu sein.
Er war ein großer Künstler, ein Künstler, der sich in der

1: Wo sich Fuchs und Hase gute Nacht sagen.
Die beiden sind seit Jahren befreundet.
Sie sind ein Paar.
Sie sind ein


***After zeroing***
Before zeroing
0: Orlando liebte von Natur aus einsame Orte, weite Ausblicke und das Gefühl, für immer und ewig zu sein.
Die Natur ist ein Paradies für sich.
Die Natur ist ein Paradies für sich

1: Wo sich Fuchs und Hase gute Nacht, die Sonne, die Sonne, die Sonne, die Sonne, die Sonne, die Sonne, die

Другие вопросы по теме