huggingface / huggingface/candle

~2x slower than `Transformer` on cpu with `Bert` model

Open
#2,204 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
21k
Forks
1.8k
Avg merge
16h 42m
Merged PRs (30d)
25

Description

OS: Windows 11
Model: [maidalun1020/bce-embedding-base_v1](https://huggingface.co/maidalun1020/bce-embedding-base_v1)

Command:
```sh
cargo run --features mkl --example bert --release -- --model-id maidalun1020/bce-embedding-base_v1 --use-pth
```
Candle(took ~15s):
```rust
let s = std::fs::read_to_string(
"test.txt",
)?;

// split text by length of 512
let mut splited_strs = vec![];
let mut cur_length = 0;
let mut tmp_str = String::new();
for ch in s.chars() {
let l = ch.len_utf8();
if cur_length + l <= 512 {
cur_length += l;
} else {
splited_strs.push(tmp_str.drain(..).collect::());
cur_length = l;
}
tmp_str.push(ch);
}

let (model, mut tokenizer) = args.build_model_and_tokenizer()?;
let device = &model.device;
let tokenizer = tokenizer
.with_padding(Some(Default::default()))
.with_truncation(Some(Default::default()))
.map_err(E::msg)?;
let mut tensors = vec![];
for s in splited_strs {
let e = tokenizer.encode(s, true).map_err(E::msg)?;
let token_ids = Tensor::new(e.get_ids(), device)?.unsqueeze(0)?;
let token_type_ids = token_ids.zeros_like()?;
tensors.push([token_ids, token_type_ids]);
}

let start = std::time::Instant::now();
for [token_ids, token_type_ids] in tensors {
model.forward(&token_ids, &token_type_ids)?;
}
println!("Took {:?} ", start.elapsed());
```

Transfomer(took ~ 8s)
```python
import time

from BCEmbedding import EmbeddingModel

# init embedding model
model = EmbeddingModel(model_name_or_path="maidalun1020/bce-embedding-base_v1")

f = open(
"test.txt",
encoding="utf8",
mode="r",
).read()

# split text by the length of 512
def split_text(characters: List[str], length: int) -> List[str]:
result: List[str] = []
current_string = ""
current_length = 0

for char in characters:
if current_length + (clen := len(char.encode("utf-8"))) <= length:
current_string += char
current_length += clen
else:
result.append(current_string)
current_string = char
current_length = clen

if current_string:
result.append(current_string)

return result

(*sentences,) = f

sentences = split_text(sentences, 512)

st = time.time()

# extract embeddings
embeddings = model.encode(sentences)

print(time.time() - st)
```
text file:
[test.txt](https://github.com/huggingface/candle/files/15401420/test.txt)

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the `examples/bert` entry point and reproduce the provided `cargo run --features mkl --example bert --release` benchmark using the linked model and `test.txt` on Windows. Compare the timed forward-pass path with the Python result, then trace the CPU execution path to identify why Candle is slower; done means explaining or resolving the performance gap with evidence from the benchmark.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, rust
Domain
machine-learning, performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.