惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Forbes - Security
Forbes - Security
H
Hackread – Cybersecurity News, Data Breaches, AI and More
N
Netflix TechBlog - Medium
Engineering at Meta
Engineering at Meta
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
F
Fortinet All Blogs
P
Privacy & Cybersecurity Law Blog
The Hacker News
The Hacker News
博客园 - 司徒正美
博客园 - 聂微东
T
The Blog of Author Tim Ferriss
I
Intezer
WordPress大学
WordPress大学
Security Archives - TechRepublic
Security Archives - TechRepublic
Scott Helme
Scott Helme
T
Threat Research - Cisco Blogs
T
Tailwind CSS Blog
月光博客
月光博客
Recent Announcements
Recent Announcements
博客园 - 叶小钗
J
Java Code Geeks
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
L
LINUX DO - 热门话题
Google DeepMind News
Google DeepMind News
C
Cyber Attacks, Cyber Crime and Cyber Security
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
N
News and Events Feed by Topic
A
Arctic Wolf
B
Blog RSS Feed
Recorded Future
Recorded Future
D
DataBreaches.Net
有赞技术团队
有赞技术团队
Project Zero
Project Zero
U
Unit 42
T
Tor Project blog
The GitHub Blog
The GitHub Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
C
CERT Recently Published Vulnerability Notes
博客园 - Franky
博客园 - 【当耐特】
Microsoft Security Blog
Microsoft Security Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Security Latest
Security Latest
C
Cisco Blogs
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Blog — PlanetScale
Blog — PlanetScale
H
Heimdal Security Blog
Vercel News
Vercel News
Stack Overflow Blog
Stack Overflow Blog
S
Securelist

Pierce Freeman

A browser for agents | Pierce Freeman The grey market of podcast appearances The way I travel | Pierce Freeman Fixing slow AWS uploads | Pierce Freeman Local tools should still use vaults We solved scratch content first Starting a podcast in 2025 Being late but still being early Automating our home video imports Adding my parents to tailscale A deep dive on agent sandboxes Language servers for AI | Pierce Freeman My simple home podcast studio We need centralized infrastructure | Pierce Freeman Coercing agents to follow conventions using AST validation My unified theory of social selling My personal backup strategy | Pierce Freeman July updates to the homelab How the KV Cache works httpx is the right way to do web requests in Python Reputation is becoming everything | Pierce Freeman Building a (kind of) invisible mac app Updated knowledge in language models Making an ascii animation | Pierce Freeman How speculative decoding works | Pierce Freeman Under the hood of Claude Code Doing things because they're easy, not hard Speeding up sideeffects with JIT in mountaineer Firehot for hot reloading in Python Misadventures in Python hot reloading How text diffusion works | Pierce Freeman The tenacity of modern LLMs The ergonomics of rails | Pierce Freeman How language servers work | Pierce Freeman Just add eggs | Pierce Freeman Unfortunately SEO still matters | Pierce Freeman The futility of human-only web requirements Setting up Input Leap | Pierce Freeman Checking in on Waymo | Pierce Freeman The react revolution | Pierce Freeman Speeding up many small transfers to a unifi nas Quick notes on swift libraries AI engineering is a different animal San Francisco | Pierce Freeman Debugging a mountaineer rendering segfault Local network config on macOS Building our home network | Pierce Freeman Introducing Envelope.dev | Pierce Freeman Legacy code and AI copilots Typehinting from day-zero | Pierce Freeman Generating database migrations with acyclic graphs Lofoten | Pierce Freeman Mountaineer v0.1: Webapps in Python and React Constraining LLM Outputs | Pierce Freeman Passthrough above all | Pierce Freeman Accuracy in kudos | Pierce Freeman How quick we are to adapt Costa Rica | Pierce Freeman Debugging chrome extensions with system-level logging Speeding up runpod | Pierce Freeman Inline footnotes with html templates Parsing Common Crawl in a day for $60 An era of rich CLI All or nothing with remote work The Next 10 Years | Pierce Freeman Adding wheels to flash-attention | Pierce Freeman LLMs as interdisciplinary agents | Pierce Freeman New Zealand | Pierce Freeman Representations in autoregressive models | Pierce Freeman Let's talk about Siri | Pierce Freeman Minimum viable public infrastructure | Pierce Freeman Reasoning vs. Memorization in LLMs Automatically migrate enums in alembic Greater sequence lengths will set us free On learning to ski | Pierce Freeman Dolomites | Pierce Freeman Using grpc with node and typescript Opportunity years | Pierce Freeman Buzzword peaks and valleys | Pierce Freeman Buenos Aires | Pierce Freeman Network routing interaction on MacOS Independent work: November recap | Pierce Freeman Debugging slow pytorch training performance The provenance of copy and paste Debugging tips for neural network training Patagonia | Pierce Freeman Santiago | Pierce Freeman My 2022 digital travel kit AWS vs GCP - GPU Availability V2 Independent work: October recap | Pierce Freeman Planning Patagonia | Pierce Freeman Relationship modeling | Pierce Freeman The power of status updates A new chapter | Pierce Freeman Give my library a coffee shop AWS vs GCP - GPU Availability V1 Switzerland | Pierce Freeman Headfull browsers beat headless | Pierce Freeman Webcrawling tradeoffs | Pierce Freeman Copenhagen | Pierce Freeman
The curious case of LM repetition
2024-01-22 · via Pierce Freeman

I was doing some OSS benchmarking over the weekend and was running into an odd issue. Some families of models would respond with near-gibberish, even with straightforward prompt inputs.

Given the low reported perplexity, I thought there had to be an issue. I refactored the core logic into a new notebook to isolate the extraneous factors. Here's the basic code:

model_dtype = torch.float32
device_map = "auto"
device = "cuda"
text = "Here's a recipe for baking chocolate chip cookies: Start by"
from transformers import AutoConfig, AutoModelForCausalLM, AutoTokenizer, TextStreamer
import torch

config = AutoConfig.from_pretrained(name_or_path)
tokenizer = AutoTokenizer.from_pretrained(name_or_path)
model = AutoModelForCausalLM.from_pretrained(
	name_or_path,
	config=config,
	torch_dtype=model_dtype,
	device_map=device_map
)

model.eval()
model.to(device)
model.to(model_dtype)

if tokenizer.pad_token_id is None:
    print("Setting pad token to EOS")
    tokenizer.pad_token = tokenizer.eos_token

def generate_output(encoded_batch):
    with torch.no_grad():
        return model.generate(
            input_ids=encoded_batch['input_ids'],
            attention_mask=encoded_batch['attention_mask'],
            max_new_tokens=250,
            temperature=1.0,
            top_p=0.95,
            top_k=50,
            repetition_penalty=1.0,
            no_repeat_ngram_size=0.0,
            use_cache=True,
            do_sample=True,
            eos_token_id=tokenizer.eos_token_id,
            pad_token_id=tokenizer.pad_token_id
        )

batch = [text]
encoded_batch = {
	key: value.to(model.device)
	for key, value in tokenizer(batch, return_tensors='pt', padding=True).items()
}

encoded_output = generate_output(encoded_batch)
decoded_output = tokenizer.batch_decode(encoded_output, skip_special_tokens=True)
print("[prompt]", text)
print("[response]", decoded_output)

Couldn't be simpler, right? Load the model, tokenize the input, and generate with some pretty common sampling defaults.

Still saw the same issue. This is the raw output (all warning messages included):

Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained.

Loading checkpoint shards: 100% 2/2 [00:35<00:00, 16.18s/it]

Setting pad token to EOS

[prompt] Here's a recipe for baking chocolate chip cookies: Start by
[response] putting a big pot pot pot pot pot pot pot pot pot pot cookie cookies
cookies cookies cookies cookies cookies cookie cookies cookies cookies cookies
chocolate chip cookie cookies chocolate chip cookies cookie chocolate chip cookie
cookie cookie cookie cookies cookie cookies cookie cookie chocolate chip cookie
cookies chocolate chip cookie cookie cookie chocolate chip cookie cookie cookie
cookie cookies cookies chocolate chip cookie cookie cookie chocolate chip cookie
cookie cookie cookie cookie chocolate chip cookie cookie cookies cookie cookie
cookies cookie cookie cookies cookie chocolate chip cookie cookie chocolate chip
cookie cookie cookie cookie cookies chocolate chip cookie cookie cookie cookie
chocolate chip cookie cookie cookie chocolate chip cookie cookie cookie ...

I like cookies. But not this much. Here were my theories and what I checked along the way.

Finetuned model format

Especially in RLHF finetuned models, training inputs will be normalized to a common prompt format. This helps to guarantee a consistency between "user" text and expected output, while allowing users to specify different prompting techniques at the system level. If you've used hosted LLMs (OpenAI, Anthropic, etc.) this mirrors their conversation creation APIs. It's what they're actually doing behind the scenes.

There are varying formats that have become defacto standards. Two of the most popular are chatml and the alpaca format.

chatml:

<|im_start|>system
You are an intelligent agent.<|im_end|>
<|im_start|>user
How are you?<|im_end|>
<|im_start|>assistant
Great! How are you?<|im_end|>

Alpaca format:

### Instruction:
You are an intelligent agent.

### Input:
How are you?

### Response:
Great! How are you?

If you're violating the prompt format that the model was finetuned on, is it possible the results will be gibberish? I doubted it, but consulted the documentation again for these models. I confirmed they were all pure pretrained models, so they weren't trained with any specific prompting format. Just for kicks, I also tried to reformat the prompt data with these common formats. Same outcome.

Next theory.

Top p, top k, and all the other generation parameters

There are a lot of sampling parameters that configure how the sample selection works when the model is auto-regressively sampling. I tried to run a hyperparam sweep on top_p, top_k, repetition_penalty and no_repeat_ngram_size. Still no dice. Results basically look the same regardless of the top_p and to_k values.

The repetition parameters did more to vary the output and get rid of the explicit repetition. They're deterministically lowering the probability of sampling certain ngrams, so this was no surprise. Unfortunately the responses were still unintelligible:

[prompt] Here's a recipe for baking chocolate chip cookies: Start by
[response] melting some chocolate chips in the oven at 375°F. While they are
baking baking, bake. Let's'ss's the the some some start start baking bake bake
baking start.. baking cookie cookie cookies cookies cookie. cookie chocolate.
chocolate cookie chips cookies baking. Let'' start Some Some..".'Let's start bake.
bake let Let Let. Some Let some.Some Let let let. let some Some SOME.Lets.StartsSome
Some Cookie.'Start baking cookies' start cookie baking'CookCook'. Start..'Start Some
Start Some 'Let'Lettingting'tughtughtrichtricht. '.. 'Some. Cookie Cookie cookie
Cookie SomeSomeCookieCookie Cookie Chocolate Chocolate cookie ChocolateCookie
Chocolate Cookie..... Lets '. ChocolateChip cookie some Cookie chocolate Chocolate
Chip Chip.." 'Cookie'Cookie'SomeCookieChipChipchipCookie.Cookie
'.CookiecookiecookieCookie.Chocolate.'.'..Cook Cook.Choc.chocococoocoCook.
CookieCook.chocolate..cook.Cook.'.' 'Cook'CookCook,Cook,Cook'Cookie' 'Cholololoolo,
'LoLo LoLoChocololLoLet'sStartStart.'

Once again, way too many cookies. The problem lay elsewhere.

Finding the culprit

From the get-go, I thought it was incredibly odd that some models worked just fine and some were displaying this strange repeating behavior. After these hyperparam sweeps turned up short, I took a step back and thought about the commonalities in the actual behavior.

The key observation was that the issue appeared to be segmented not by the model itself, but by the different family of models. Whether the models were 500M, 3B, or 7B it was an issue of family instead of the model size. Other families of the same side worked just fine.

This led me to two theories:

  • Either the huggingface code implementing these families is broken. Possible, but unlikely given the relative popularity of some of these models.
  • Some family specific parameters that are being disabled at the configuration level.

I parsed through the AutoConfig configuration parameters. Nothing jumped out. But then I thought, what else controls model logic? Throwing caution out the window, I enabled all the conservative flags: downloading fresh parameters for the model, clearing the cache directories, and trusting remote code.

Ding ding ding. We have a winner. The key was trust_remote_code=True.

config = AutoConfig.from_pretrained(name_or_path, trust_remote_code=True)
tokenizer = AutoTokenizer.from_pretrained(name_or_path, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
	name_or_path,
	config=config,
	torch_dtype=model_dtype,
	device_map=device_map,
    trust_remote_code=True,
)
[prompt] Here's a recipe for baking chocolate chip cookies: Start by
[response] combining 1 cup of softened butter with 1 ¼ cups of white sugar.
In a separate bowl, stir together 1 egg, 2 teaspoons of vanilla extract, and 1 ½ cups
all-purpose flour. If desired, you can toss in 1 teaspoon of cinnamon or ¼ teaspoon
each of salt and baking soda. The last ingredient you'll need is about a ¾ cup (11.4
ounces) of semisweet chocolate chips.

Dump the egg mixture into a large mixing bowl and add the butter and sugar, stirring
vigorously until they're combined. Add the dry mixture, along with the chocolate, to
the bowl. Now, using a spoon or spatula, fold the ingredients together until the
cookie dough is evenly mixed. After that, prepare two sheets of parchment paper.
Divide the dough into one-inch balls, then place the balls on the parchment. Take one
of the sheets and place it in the oven at 350 degrees for 8-9 minutes. While the
cookies bake, use another pan, grease it with olive oil, place six pieces of salmon,
season with sea salt, squeeze half of a lime over them, cover with plastic wrap,
refrigerate for about twenty minutes, bake it on each side for approximately 3 to 4
minutes

Okay, so what's going on here? My theory:

Before new model architectures are merged into the official transformers library, the only way to run them is with trust_remote_code=True. For these new models, code is typically published alongside the model weights within the huggingface model hub. You can see this most clearly in novel architectures that were published within the last few months:

![](/notes-images/llm_repetition/Screenshot%202024-01-22%20at%202.25.40 PM.png)

When the model weights are downloaded, the code files are as well. Inference will execute this code in order to run the model. Hence the notion of remote-code. It's typically not ideal to allow arbitrary remote code execution, which is why this flag is off by default.

Architectures will then go through a review process and land in mainline transformers. After that, it's no longer required to trust remote code. If the model artifacts specify the architecture type (llama, phi, mpt, etc.) the transformers library will map the remote model weights to the local code implementation baked into transformers.

Now - what happened here? It seems that the transformers implementation has subtly skewed from its original source. It didn't skew enough to invalidate the weight files and cause a load error, which means that the parameters are loaded in according to specification. But the logic did skew enough to start generating incorrect outputs, at least with some artifact files.

Moral of the story: If you're in an isolated environment and can risk remote code execution, it's worth using the published artifacts to establish your baseline of model execution. This gives you the closest proxy to what was actually used to train the model. Everything else - including optimized code after the fact - might be better, but it's a hypothesis to test alongside with other performance guarantees.