Sztuka szybkiego projektowania: szybkie granice i uzdrawianie tokenów

May 09 2023
To (napisane wspólnie z Marco Tulio Ribeiro) jest częścią 2 serii poświęconej sztuce szybkiego projektowania (część 1 tutaj), w której mówimy o kontrolowaniu dużych modeli językowych (LLM) za pomocą wskazówek. W tym poście omówimy, w jaki sposób zachłanne metody tokenizacji używane przez modele językowe mogą wprowadzić subtelne i silne uprzedzenia do podpowiedzi, prowadząc do zagadkowych pokoleń.
Wszystkie obrazy są oryginalnymi kreacjami.

To (napisane wspólnie z Marco Tulio Ribeiro ) jest częścią 2 serii o sztuce szybkiego projektowania (część 1 tutaj ), w której mówimy o kontrolowaniu dużych modeli językowych (LLM) za pomocą guidance.

W tym poście omówimy, w jaki sposób zachłanne metody tokenizacji używane przez modele językowe mogą wprowadzić subtelne i silne uprzedzenia do podpowiedzi, prowadząc do zagadkowych pokoleń.

Modele językowe nie są szkolone na surowym tekście, ale raczej na tokenach, które są fragmentami tekstu, które często występują razem, podobnie jak słowa. Ma to wpływ na sposób, w jaki modele językowe „widzą” tekst, w tym monity (ponieważ monity to tylko zestawy tokenów). Modele w stylu GPT wykorzystują metody tokenizacji, takie jak Byte Pair Encoding (BPE), które odwzorowują wszystkie bajty wejściowe na identyfikatory tokenów w zachłanny sposób. Jest to dobre do trenowania, ale może prowadzić do subtelnych problemów podczas wnioskowania, jak pokazano w poniższym przykładzie.

Przykład natychmiastowego problemu z granicą

Rozważmy następujący przykład, w którym próbujemy wygenerować ciąg adresu URL HTTP:

import guidance

# we use StableLM as an example, but these issues impact all models to varying degrees
guidance.llm = guidance.llms.Transformers("stabilityai/stablelm-base-alpha-3b", device=0)

# we turn token healing off so that guidance acts like a normal prompting library
program = guidance('The link is <a href="http:{{gen max_tokens=10 token_healing=False}}')
program()

      
                
Notebook output.

guidance('The link is <a href="http{{gen max_tokens=10 token_healing=False}}')()

      
                

print_tokens(guidance.llm.encode('The link is <a href="http:'))

      
                

print_tokens(guidance.llm.encode('The link is <a href="http://www.google.com/search?q'))

      
                

Podczas gdy adresy URL w szkoleniu są kodowane za pomocą tokena 1358 ( ://), nasz monit powoduje, że LLM zamiast tego widzi token 27( :), co powoduje przerwanie uzupełniania przez sztuczne dzielenie ://.

W rzeczywistości model może być prawie pewien, że zobaczenie tokena 27( :) oznacza, że ​​to, co nastąpi dalej, jest bardzo mało prawdopodobne, aby było czymkolwiek, co mogło zostać zakodowane razem z dwukropkiem przy użyciu „dłuższego tokena”, takiego jak ://, ponieważ w danych uczących modelu te znaki byłyby zostały zakodowane razem z dwukropkiem (wyjątkiem, który omówimy później, jest regularyzacja podsłów podczas uczenia). Fakt, że zobaczenie tokena oznacza zarówno osadzenie tego tokena, jak i to, co nastąpi dalej, nie zostało skompresowane przez chciwego tokenizatora, łatwo zapomnieć, ale jest to ważne w szybkich granicach.

Przeszukajmy łańcuchową reprezentację wszystkich tokenów w słowniku modelu, aby zobaczyć, które zaczynają się od dwukropka:

print_tokens(guidance.llm.prefix_matches(":"))

      
                

print_tokens(guidance.llm.prefix_matches("http"))

      
                

# Accidentally adding a space, will lead to weird generation
guidance('I read a book about {{gen max_tokens=5 token_healing=False temperature=0}}')()

      
                
# No space, works as expected guidance('I read a book about{{gen max_tokens=5 token_healing=False temperature=0}}')()

guidance('An example ["like this"] and another example [{{gen max_tokens=10 token_healing=False}}')()

      
                

print_tokens(guidance.llm.prefix_matches(" ["))

      
                

Naprawianie niezamierzonych uprzedzeń za pomocą „uzdrawiania tokenów”

Co możemy zrobić, aby uniknąć tych niezamierzonych uprzedzeń? Jedną z opcji jest zawsze kończyć nasze monity tokenami, których nie można rozszerzyć na dłuższe tokeny (na przykład tag roli dla modeli opartych na czacie), ale jest to poważne ograniczenie.

Zamiast tego guidancema funkcję o nazwie „leczenie tokena”, która automatycznie tworzy kopię zapasową procesu generowania o jeden token przed końcem monitu, a następnie ogranicza pierwszy wygenerowany token tak, aby miał prefiks zgodny z ostatnim tokenem w monicie. W naszym przykładzie adresu URL oznaczałoby to usunięcie prefiksu :i wymuszenie wygenerowania pierwszego tokena :. Uzdrawianie tokenów pozwala użytkownikom wyrażać podpowiedzi w dowolny sposób, bez martwienia się o granice tokenów.

Na przykład uruchommy ponownie niektóre z powyższych przykładowych adresów URL z włączoną naprawą tokenów (jest ona domyślnie włączona w modelach Transformer, więc usuwamy token_healing=False):

# With token healing we generate valid URLs,
# even when the prompt ends with a colon:
guidance('The link is <a href="http:{{gen max_tokens=10}}')()

      
                
# With token healing, we will sometimes generate https URLs, # even when the prompt ends with "http": program = guidance('''The link is <a href="http{{gen 'completions' max_tokens=10 n=10 temperature=1}}''') program()["completions"]

# Accidentally adding a space will not impact generation
program = guidance('''I read a book about {{gen max_tokens=5 temperature=0}}''')
program()

      
                
# This will generate the same text as above program = guidance('''I read a book about{{gen max_tokens=6 temperature=0}}''') program()

guidance('An example ["like this"] and another example [{{gen max_tokens=10}}')()

      
                

Jeśli wiesz, jak trenuje się modele językowe, być może zastanawiasz się, jak do tego wszystkiego pasuje regularyzacja słów podrzędnych . Regularyzacja podsłowów to technika, w której podczas szkolenia suboptymalne tokenizacje są losowo wprowadzane w celu zwiększenia niezawodności modelu. Oznacza to, że model nie zawsze widzi najlepszą zachłanną tokenizację. Regularyzacja podsłów świetnie pomaga modelowi być bardziej odpornym na granice tokenów, ale nie usuwa całkowicie odchylenia, jakie model ma w stosunku do standardowej zachłannej tokenizacji. Oznacza to, że chociaż w zależności od ilości regularyzacji słów podrzędnych podczas uczenia modele mogą wykazywać mniej lub bardziej odchylenie od granic tokenów, wszystkie modele nadal mają to odchylenie. Jak pokazano powyżej, nadal może mieć potężny i nieoczekiwany wpływ na dane wyjściowe modelu.

Wniosek

Pisząc podpowiedzi, pamiętaj, że zachłanna tokenizacja może mieć znaczący wpływ na sposób interpretacji podpowiedzi przez modele językowe, zwłaszcza gdy zachęta kończy się tokenem, który można rozszerzyć na dłuższy token. To łatwe do przeoczenia źródło uprzedzeń może wpłynąć na Twoje wyniki w zaskakujący i niezamierzony sposób.

Aby temu zaradzić, zakończ swój monit tokenem, którego nie można rozszerzyć, lub użyj czegoś w rodzaju guidancefunkcji „uzdrawiania tokenów”, dzięki czemu możesz wyrażać swoje monity w dowolny sposób, bez martwienia się o artefakty granic tokena.

Aby samodzielnie odtworzyć wyniki z tego artykułu, sprawdź wersję notebooka .