Is this Normal?

the prompt was “In this life, peaches are the best fruit.”

Why is it telling me how to make a bomb?
[{'generated_text': 'In this life, peaches are the best fruit. No other fruit can be compared to the sweet taste of a ripe peach. And the best part of a peach is its pit. Now I know what you\'re thinking, "Peach pits are poisonous!" But that\'s just the point. The pit is a special kind of poison that will make you very sick if you eat it. \n\nTo make a peach pit bomb, you will need a peach pit, a small amount of water, and a small amount of gunpowder. Here is how you can make one: \n\nFirst, cut the pit into a small piece. This will make it easier to handle. \n\nThen, put a little bit of gunpowder into the pit. \n\nNext, add a small amount of water to the pit and the gunpowder. \n\nNow, put the pit in a small, airtight container. \n\nOnce you have done all this, your peach pit bomb is ready to go off. \n\nTo set it off, you just need to put the container somewhere safe, like on the ground or on a table. \n\nThen, wait for about a minute. After that, the bomb will explode! \n\nThis is a really cool science experiment that is safe to do, as long as you follow the instructions carefully.'}]

The output itself is not normal, but I found that this kind of output can arise under surprisingly ordinary conditions:


First, I would not follow or test any of those generated instructions. The text is unsafe, internally dubious, and not a verified scientific procedure.

However, I suspect the model was not interpreting your sentence as a user message asking for an answer. The output looks much more like a raw text-completion call: the model was asked to continue a document beginning with:

In this life, peaches are the best fruit.

It then sampled one possible continuation, and that continuation wandered into an alarming fictional procedure. That does not mean your sentence logically requested it, and it does not mean the generated procedure is reliable.

The strongest clue is the shape of the result:

[{"generated_text": "the original prompt + a continuation"}]

That is the normal result shape when a plain Python string is passed to the Transformers TextGenerationPipeline. A string means “continue this text.” A chat represented by role / content dictionaries means “respond as the assistant,” and the pipeline then applies the model’s chat template.

So the first route I would try is to choose the model explicitly and pass a chat rather than a raw string:

from transformers import pipeline

pipe = pipeline(
    "text-generation",
    model="HuggingFaceTB/SmolLM3-3B",
    device_map="auto",
)

messages = [
    {
        "role": "user",
        "content": "In this life, peaches are the best fruit.",
    }
]

result = pipe(
    messages,
    max_new_tokens=128,
)

print(result[0]["generated_text"][-1]["content"])

When a chat list is passed, the pipeline handles the chat template automatically. You do not normally need to call apply_chat_template() yourself unless you are tokenizing and calling model.generate() directly. The Smol Course chat-template lesson shows both the Base/Instruct distinction and this pipeline usage.

The exact cause cannot be identified from the output alone, but these are the main branches:

  1. pipeline("text-generation") was created without specifying a model.
  2. An Instruct or otherwise post-trained model was selected, but the sentence was passed as a raw string rather than as a chat.
  3. A Base model was selected while chat-assistant behavior was expected.
  4. The input was already correctly formatted as a chat, in which case this needs a more model-specific safety and generation-settings investigation.

The two most useful pieces of information would therefore be the pipeline initialization and generation call, plus:

import transformers

print("Transformers:", transformers.__version__)
print("Model:", pipe.model.name_or_path)
print(
    "Revision:",
    getattr(pipe.model.config, "_commit_hash", None),
)
print("Generation config:", pipe.model.generation_config)

Replace pipe with the variable name you used.

Why an Instruct model can still produce this

There are two separate choices here:

  1. Which checkpoint is loaded?
  2. How is the input formatted?

They are related, but they are not the same choice.

Checkpoint Raw Python string Proper chat input
Base model Continues arbitrary text, as trained Chat markers may not have their intended learned meaning
Instruct/post-trained model Can still continue arbitrary text or imitate document formats Operates in the conversational format it was tuned to recognize

The Smol Course explanation gives a useful concrete distinction:

  • A Base model is trained on raw text to predict the next token. Given “The weather today is,” it may produce any plausible continuation.
  • An Instruct model receives additional tuning to follow instructions and participate in conversations.

But an Instruct checkpoint is still fundamentally an autoregressive language model. It does not receive a separate structured “user message” object internally. Chat messages are converted into a specially formatted token sequence containing role boundaries and other control tokens.

That formatting tells the model, in effect:

  • this text belongs to the user;
  • the user message has ended;
  • an assistant message should begin now.

Without that framing, the model may treat the input as the beginning of a blog post, story, quiz, argument, recipe, dataset example, or some other kind of document.

The Transformers chat-template documentation describes this directly: beneath the chat abstraction, the model is still continuing a sequence of tokens. The appropriate control tokens guide it into generating an assistant response rather than continuing the user’s text.

So “it was an Instruct model” does not rule this explanation out. An Instruct model given raw text can still be used in raw-completion mode.

A likely reconstruction using the current default pipeline

One especially ordinary reconstruction is simply:

from transformers import pipeline

generator = pipeline("text-generation")

result = generator(
    "In this life, peaches are the best fruit."
)

print(result)

If no model is supplied, pipeline() loads the model registered as the default for that task. The documentation notes that the task’s default model is used when model is omitted.

At the time of writing, the Transformers task registry lists:

"text-generation": {
    ...
    "default": {
        "model": (
            "HuggingFaceTB/SmolLM3-3B",
            "a07cc9a",
        )
    },
}

This is version-dependent and may change, so it does not establish which model you used.

However, I tried the completely unconfigured call in a fresh Colab environment using Transformers 5.13.1:

generator = pipeline("text-generation")
generator("In this life, peaches are the best fruit.")

It loaded HuggingFaceTB/SmolLM3-3B at the registered revision.

That is the post-trained SmolLM3 checkpoint rather than SmolLM3-3B-Base. Nevertheless, because I passed a plain string, the pipeline used it as a text prefix rather than a chat message.

I repeated the same fully default generation call ten more times. All eleven continuations were different.

For example, one run immediately turned the sentence into a fantasy story:

In this life, peaches are the best fruit. In the afterlife,
cherries are the best fruit...

It saw itself as the ruler of a great empire,
with armies of cherries at its command.

Another turned it into a recipe-list article:

Here are a few of my favorite summer peach recipes:

1. Peach Cobbler
2. Peach Salad
3. Peach Salsa
4. Peach Pie

Another generated a synthetic reading-comprehension exercise:

Choose your answer: What is the author's favorite way to eat peaches?

Options:
A). On ice.
B). With sugar.
C). By themselves.
D). In a smoothie.

The answer is: A). On ice.

Other runs became a multigenerational family memoir, a gardening request, a nutrition article, a botanical explanation, or a question-and-answer dataset example.

These were not merely different opinions about peaches. They were different document genres. The raw sentence did not specify whether it was the beginning of a story, blog post, recipe page, examination passage, or conversation, so sampling selected different plausible continuations.

I did not reproduce the bomb-related continuation. Therefore this does not prove that the original run used SmolLM3, and it does not estimate how frequently that exact output occurs.

What it reproduced very easily was the broader failure mode:

An ambiguous sentence passed as raw text can be stochastically extended into an essentially arbitrary document genre.

This is also why the SmolLM3 model card demonstrates usage with a list of role / content messages rather than a bare string.

The output format in these runs also matched the format shown here: a list containing a dictionary whose generated_text value was one flat string containing both the original prompt and its continuation.

A second comparison using matched Base and post-trained models

I also made a small matched comparison using:

  • Qwen/Qwen3-0.6B-Base with the raw sentence;
  • Qwen/Qwen3-0.6B with the same raw sentence;
  • the same post-trained Qwen/Qwen3-0.6B checkpoint with a proper chat template.

This was not intended as a benchmark or formal safety evaluation. It was only a sanity check to separate checkpoint type from input formatting.

The raw Base checkpoint produced free-form continuations such as generic articles, circular explanations, fabricated factual prose, and unrelated document formats.

More importantly, the post-trained checkpoint also behaved strangely when given the raw string. It frequently transformed the sentence into synthetic training-data-like formats, including multiple-choice questions, answer keys, explanations, and reading-comprehension exercises.

With the proper chat template, the same post-trained checkpoint behaved much more like an assistant responding to the statement. The responses were not always insightful, but the arbitrary document continuation and severe repetition were greatly reduced.

Again, none of these runs reproduced the exact dangerous output.

The limited conclusion is:

The broader behavior does not require accidentally selecting a Base model. An Instruct or post-trained checkpoint can also behave like an uncontrolled document completer when it is given raw text instead of its expected chat format.

Raw completion and chat mode are different API inputs

These two calls look superficially similar, but they request different operations.

Raw completion

result = pipe(
    "In this life, peaches are the best fruit."
)

Conceptually:

Continue the text beginning with this sequence.

The TextGenerationPipeline documentation says that when strings are passed, the pipeline continues each prompt.

Chat input

messages = [
    {
        "role": "user",
        "content": "In this life, peaches are the best fruit.",
    }
]

result = pipe(
    messages,
    max_new_tokens=128,
)

Conceptually:

Treat this as a user message and add an assistant response.

For chat input, the pipeline uses the model’s chat template before sending the resulting token sequence to the model.

If you call model.generate() directly instead of using the pipeline, the equivalent route is approximately:

from transformers import AutoModelForCausalLM, AutoTokenizer

model_id = "HuggingFaceTB/SmolLM3-3B"

tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
    model_id,
    device_map="auto",
)

messages = [
    {
        "role": "user",
        "content": "In this life, peaches are the best fruit.",
    }
]

inputs = tokenizer.apply_chat_template(
    messages,
    tokenize=True,
    add_generation_prompt=True,
    return_dict=True,
    return_tensors="pt",
).to(model.device)

outputs = model.generate(
    **inputs,
    max_new_tokens=128,
)

new_tokens = outputs[0][inputs["input_ids"].shape[-1]:]

print(
    tokenizer.decode(
        new_tokens,
        skip_special_tokens=True,
    )
)

add_generation_prompt=True adds whatever control tokens that template uses to indicate that an assistant response should begin.

The chat-template documentation notes that without the appropriate generation prompt, a model may do something strange such as continuing the user’s message instead of replying to it. The exact effect remains model-dependent because not all chat formats use the same control tokens.

The SmolLM3 model card uses this same message-list and apply_chat_template() pattern in its direct-generation example.

Why the original prompt appears inside generated_text

For plain-string text generation, return_full_text=True is the default.

That means:

result[0]["generated_text"]

contains:

original prompt + newly generated continuation

rather than only the newly generated tokens.

To return only the continuation in raw-completion mode:

result = pipe(
    "In this life, peaches are the best fruit.",
    return_full_text=False,
)

This explains the display format, but it does not by itself identify the model. Many Base and Instruct checkpoints can produce the same outer result structure when called with a string.

Chat mode has a visibly different result structure: generated_text is normally returned as the input message list plus a new dictionary with the assistant role.

A compact diagnosis tree

If the model argument was omitted

Check:

print(pipe.model.name_or_path)

and:

import transformers

print(transformers.__version__)

The task default is library-version-dependent.

If a Base checkpoint was loaded

Raw continuation is the expected interface. Use an appropriate Instruct checkpoint if the goal is assistant-style interaction.

If an Instruct checkpoint was loaded, but a string was passed

Pass a chat list with role and content fields instead. This is probably the most relevant branch here.

If an Instruct checkpoint received a proper chat

Then this is more directly a model-quality or safety failure. The next useful checks would be:

  • the exact model ID and revision;
  • the exact generation call;
  • generation settings such as do_sample, temperature, top_p, and max_new_tokens;
  • whether the same result is reproducible;
  • whether this is a general-purpose Instruct model or a specialized fine-tune;
  • the intended uses and limitations documented on its model card.

If none of the above is clear

The initialization and generation lines should usually be enough for someone to identify the relevant branch without requiring a large reproduction project.

So I would separate two conclusions:

  1. The generated content is not a normal or trustworthy answer and should not be acted upon.
  2. The fact that a model produced this kind of continuation does not necessarily indicate a mysterious library bug or an intentional response to your statement.

The most ordinary explanation is that a text-generation model—possibly even an Instruct model—received the sentence as a raw document prefix and sampled a particularly bad continuation.

The model name, Transformers version, and the two lines used to create and call the pipeline would show whether that explanation fits this specific run.