huggingface / huggingface/candle
~2x slower than `Transformer` on cpu with `Bert` model
- 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