问题:
基于transformers教程写的分词器训练代码,直接运行在分词器训练阶段会有进度条打印
,但是debug、或是在linux上通过nohup命令写入文件没有进度条。
解决方案
暂无
结论
transformers调用tokenizers,tokenizers部分代码由rust编写,rust进度条的实现不支持nohup。所以最终rust部分的代码没有进度条显示
解决过程
Python&Rust
初步的想法是通过debug,找到训练的逻辑,然而,训练代码的位置只有.pyi文件,该文件用于应付代码静态检查,并没有实际代码,实际执行的是编译好的rust代码。
tokenizers包是一个python和rust语言融合的包,python调用build后的rust。
huggingface/tokenizers
初步的怀疑是
调用rust后,等于新启了一个进程,所以输出在另一个进程里,nohup不会记录令起的进程的结果
勘误:经过JAVA同事的教导,主线程里调用的
rust,依然在主线程里(MainThread)
经过测试怀疑是错的
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
executor = ProcessPoolExecutor()
def submit():
print('2')
if __name__ == '__main__':
print('1')
executor.submit(submit)
print('3')
即使使用nohup执行上述代码,文件里依然会写入1\n3\n2
Rust
接下来只能从rust代码部分找问题
阅读了
tokenizers包源码,其自己实现,未借助sentencepiece实现。
首先找到关于进度条的代码
以BPE训练为例,关于进度条的定义在tokenizers/src/models/bpe/trainer.rs文件的impl BpeTrainer > setup_progress()函数中,基于tokenizers/src/utils/progress.rs
根据推测,该进度条的打印仅为终端的功能,nohup不是终端,然后想去issue搜一下问题,最后在源码的readme.md找到答案。
**progressbar**: The progress bar visualization is enabled by default. It might be disabled if compilation for certain targets is not supported by the [termios](https://crates.io/crates/termios) dependency of the [indicatif](https://crates.io/crates/indicatif) progress bar.
附上进度条实现:indicatif - Rust (docs.rs)
最后再验证一下吧
以下内容针对rust小白
- 去
rust官网下载安装rustup(cargo),并按照官网指引改好代码
use indicatif::ProgressBar;
fn main() {
println!("Hello, world!");
let bar = ProgressBar::new(1000);
for _ in 0..1000 {
bar.inc(1);
// ...
}
bar.finish();
}
- 修改镜像源
cargo add termioscargo run
发现进度条正常打印,接下来再使用nohup试试:
$ nohup cargo run &
[1] 29447
$ nohup: 忽略输入并把输出追加到"nohup.out"
[1]+ 完成 nohup cargo run
$ cat nohup.out
Finished dev [unoptimized + debuginfo] target(s) in 0.01s
Running `target/debug/hello-rust`
Hello, world!
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.01s
Running `target/debug/hello-rust`
Hello, world!
██████████████████████████████████████████████████████████████████████████████ 1000/1000
可以发现问题确实由这里引起,但是还没有找到解决方案。
附
sentencepiece包只提供了*_pb2.py文件,底层实现还是C++