darnahsan
Using Phi3.5 wih Bumblebee: (ArgumentError) could not match the class name "Phi3ForCausalLM" to any of the supported models
I am trying to see how I can use different HF models with Bumblebee. I am trying to load microsoft/Phi-3.5-mini-instruct
{:ok, microsoft} = Bumblebee.load_model({:hf, "microsoft/Phi-3.5-mini-instruct"})
and getting following error.
** (ArgumentError) could not match the class name "Phi3ForCausalLM" to any of the supported models, please specify the :module and :architecture options
(bumblebee 0.5.3) lib/bumblebee.ex:409: Bumblebee.do_load_spec/4
(bumblebee 0.5.3) lib/bumblebee.ex:578: Bumblebee.maybe_load_model_spec/3
(bumblebee 0.5.3) lib/bumblebee.ex:566: Bumblebee.load_model/2
#cell:etc7eozxbver4bzi:1: (file
but the lib/bumblebee.ex list Phi3ForCausalLM. Shouldn’t it be able to load this as module and architecture are listed there ? Am I missing something as just started exploring this space
Marked As Solved
jonatanklosko
Oh, you mean the model repeats words, not that it gets stuck without output. So that is not a bug, it’s just how the model behaves under the given configuration.
There are several factors that determine the model output. First of all, sometimes the model has a separate “base” and “instruct” checkpoints. Base models are trained on a bunch of text to get “text understanding”, and instruct models are further fine-tuned on conversations and tasks, to make them more usable in a chat-like interaction. For example, there is HuggingFaceTB/SmolLM-1.7B and HuggingFaceTB/SmolLM-1.7B-instruct, you probably want to use the latter.
Next, you want to make sure you use a prompt relevant for the given model. Instruct checkpoints usually have a certain template for specifying the conversation history. With the transformers Python library you can specify a template on the tokenizer, however it use a Python-specific template, so we can’t reliably load it. However, you can find the template by looking for “chat_template” in tokenizer_config.json in the given repo. Sometimes the template is also present in the model readme. Continuing with SmolLM instruct, the template is here. So here is the prompt with template:
prompt = """
<|im_start|>user
Complete the paragraph: our solar system is<|im_end|>\
<|im_start|>assistant
"""
It results in a much better result.
Finally you can make the output non-deterministic (and more creative) by using a sampling strategy for the generation, such as this:
generation_config =
Bumblebee.configure(generation_config,
strategy: %{type: :multinomial_sampling, top_p: 0.6}
)
(Sidenote: there is also :no_repeat_ngram_length to explicitly avoid repetitions, however it is a trade-off, because sometimes there are longer pharses, city names, etc, and preventing the model from reusing them worsens the usability)
Also Liked
jonatanklosko
@darnahsan I fixed the rope scaling, so you should be able to get pass that error on Bumblebee main : )
darnahsan
Bumblebee 101
Mix.install([
{:bumblebee, [github: "elixir-nx/bumblebee", override: true]},
{:nx, "~> 0.8.0", [override: true]},
{:exla, "~> 0.8.0", [override: true]},
{:kino, "~> 0.14.0", [override: true]},
{:kino_bumblebee, [github: "livebook-dev/kino_bumblebee", override: true]},
{:kino_db, "~> 0.2.12"}
])
Nx.global_default_backend({EXLA.Backend, client: :host})
Untitled
hf_token = System.fetch_env!("LB_HF_TOKEN")
{:ok, bert} = Bumblebee.load_model({:hf, "google-bert/bert-base-uncased"})
{:ok, tokenizer} = Bumblebee.load_tokenizer({:hf, "google-bert/bert-base-uncased"})
serving = Bumblebee.Text.fill_mask(bert, tokenizer)
text_input = Kino.Input.text("Sentence with mask", default: "The capital of [MASK] is Paris.")
text = Kino.Input.read(text_input)
Nx.Serving.run(serving, text)
phi3_5 = {:hf, "microsoft/Phi-3.5-mini-instruct"}
t5_flant = {:hf, "google/flan-t5-large"}
smollm = {:hf, "HuggingFaceTB/SmolLM-1.7B"}
llama_minitron = {:hf, "nvidia/Llama-3.1-Minitron-4B-Width-Base"}
repo = phi3_5
{:ok, model} = Bumblebee.load_model(repo)
{:ok, tokenizer} = Bumblebee.load_tokenizer(repo)
{:ok, generation_config} = Bumblebee.load_generation_config(repo)
generation_config = Bumblebee.configure(generation_config, max_new_tokens: 256)
serving = Bumblebee.Text.generation(model, tokenizer, generation_config,
compile: [batch_size: 1, sequence_length: 256],
stream: true,
defn_options: [compiler: EXLA]
)
Kino.start_child({Nx.Serving, name: Model, serving: serving})
prompt = "Complete the paragraph: our solar system is"
Nx.Serving.batched_run(Model, prompt) |> Enum.each(&IO.write/1)
jonatanklosko
It was added after the last release, so try bumblebee main : )
jonatanklosko
Llama3.1-Minitron and SmolLM models are outputting garbage
I tried nvidia/Llama-3.1-Minitron-4B-Width-Base and it worked fine, but SmolLM has another option related to parameters that we didn’t respect, hence the debug message. I’ve just fixed it on main and HuggingFaceTB/SmolLM-1.7B-Instruct also works.
For the record, here’s the notebook:
Notebook
# llama3
```elixir
Mix.install([
{:bumblebee, github: "elixir-nx/bumblebee"},
{:nx, "~> 0.8.0", override: true},
{:exla, "~> 0.8.0", override: true},
{:kino, "~> 0.14.0"}
])
Nx.global_default_backend(EXLA.Backend)
```
## Section
```elixir
# repo = {:hf, "nvidia/Llama-3.1-Minitron-4B-Width-Base"}
repo = {:hf, "HuggingFaceTB/SmolLM-1.7B-instruct"}
{:ok, model_info} = Bumblebee.load_model(repo)
{:ok, tokenizer} = Bumblebee.load_tokenizer(repo)
{:ok, generation_config} = Bumblebee.load_generation_config(repo)
:ok
```
<!-- livebook:{"output":true} -->
```
12:14:16.182 [info] Loaded cuDNN version 90400
```
<!-- livebook:{"output":true} -->
```
:ok
```
```elixir
generation_config =
Bumblebee.configure(generation_config,
max_new_tokens: 256
# strategy: %{type: :multinomial_sampling, top_p: 0.6}
)
serving =
Bumblebee.Text.generation(model_info, tokenizer, generation_config,
compile: [batch_size: 1, sequence_length: 256],
stream: true,
defn_options: [compiler: EXLA]
)
Kino.start_child({Nx.Serving, name: Llama, serving: serving})
```
<!-- livebook:{"output":true} -->
```
{:ok, #PID<0.261.0>}
```
```elixir
prompt = "Complete the paragraph: our solar system is"
Nx.Serving.batched_run(Llama, prompt) |> Enum.each(&IO.write/1)
```
<!-- livebook:{"output":true} -->
```
a vast and complex system of celestial bodies that orbit around the sun. The planets in our solar system are divided into two categories: terrestrial planets and gas giants. The terrestrial planets are rocky and have a solid surface, while the gas giants are composed mostly of hydrogen and helium gases. The four terrestrial planets are Mercury, Venus, Earth, and Mars, while the four gas giants are Jupiter, Saturn, Uranus, and Neptune. The gas giants are much larger than the terrestrial planets, with Jupiter being the largest. The gas giants are also much more massive than the terrestrial planets, with Jupiter being over 10 times larger than Earth. The gas giants are also much more distant from the sun than the terrestrial planets, with Jupiter being over 10 times farther away than Earth.
```
<!-- livebook:{"output":true} -->
```
:ok
```
LIVEBOOK_HF_TOKEN
All env vars with LIVEBOOK_ prefix are used to configure Livebook itself and we remove them from env on startup, that’s why it is not propagated to the runtime. You can make it LB_HF_TOKEN and it should work. You can also set the token using Livebook secrets, see the lock icon in the session sidebar.
jonatanklosko
Thanks, managed to have the models run on CPU though they tend to get stuck in a loop after couple of sentences
.
If you can provide a notebook that reproduces it, I can have a look : )
Regarding ollama, if there is quantization is involved then that is definitely a major memory usage reduction. There was a recent work to support quantization in Axon, but currently it still requires loading the full-precision parameters first and converting to quantized version.







