나는 사용하고있다속삭임.cpp일부 사운드 파일을 복사합니다. 이는 CPU 집약적인 프로세스이므로 최적의 설정을 찾으려고 노력하여 스레드 설정(-t)으로 몇 가지 테스트를 수행했지만 결과는 매우 혼란스러웠습니다. 내가 실행한 명령은 다음과 같습니다.
date; time ./main -t [number of threads] -m ggml-model.bin -f 5min-16kHz.wav; date
저는 6개 코어(+ 6개 하이퍼스레딩 코어)를 갖춘 Intel i7이 탑재된 Macbook Pro에서 이것을 실행하고 있습니다.
기본 설정(4개 스레드), 6개 및 12개 스레드(모든 CPU가 100%에서 실행되었음에도 불구하고 출력이 생성되지 않은 14개 스레드)를 시도했습니다. 결과는 다음과 같습니다.
스레드 | 시간 출력 |
---|---|
4 | 1750.84초 사용자 11.02초 시스템 564% CPU 5:11.87 총 |
4 | 1862.04s 사용자 18.63s 시스템 553% CPU 5:39.58 총 |
6 | 2199.42초 사용자 16.79초 시스템 720% CPU 5:07.51 총 |
6 | 2212.72초 사용자 14.49초 시스템 722% CPU 5:08.22 총 |
12 | 4595.03초 사용자 22.21초 시스템 1053% CPU 7:18.47 총 |
12 | 4298.11s 사용자 22.53s 시스템 1059% CPU 6:47.85 총 |
보시다시피 스레드 수가 증가하면 CPU 부하도 증가합니다. CPU 로드가 증가함에 따라 실시간 시간이 비례적으로 감소할 것으로 예상할 수 있지만(1분 동안 100%는 대략 30분 동안 200%, 2분 동안 50%에 해당) 여기서는 그런 일이 발생하지 않습니다.
대신 4개 및 6개 스레드를 사용해도 거의 동일한 실시간 결과를 얻었으며, 6개 스레드를 실행할 때 CPU 사용량이 약 25% 증가했습니다. 12개의 스레드는 더욱 악화되어 6개의 스레드에 비해 CPU 시간은 두 배로 늘어나고 실시간은 40% 증가합니다.
나는 그것을 이해하지 못한다. 물론 더 많은 스레드가 선형적으로 확장되지는 않지만동일한 작업을 수행할 때 CPU 시간은 스레드 수에 관계없이 상당히 일정하게 유지되어야 합니다. 그렇죠? CPU 사용량이 증가하면 실시간이 감소해야 합니까?
작업과 하드웨어를 고려할 때 사용할 스레드 수에 대한 합리적인 설정은 무엇입니까?스레드가 I/O를 기다리는 경우를 대비해 코어 수 + 약간의 추가가 될 것으로 예상합니다. 제가 작업 중인 사운드 파일은 10MB이고, Whisper.cpp는 32GB 시스템에서 약 3,6GB를 사용합니다(현재 약 10GB는 사용되지 않으며 메모리 부족은 "녹색"입니다).
편집: 하나의 스레드만 사용하는 해당 값(-t 1):
1619.90초 사용자 20.86초 시스템 197% CPU 13:48.78 총
한 스레드가 CPU의 거의 200%를 사용하고 있음을 알 수 있습니다. 내가 이것을 이해하는지 잘 모르겠습니다. 하지만 실제 시간의 13분은 의미가 있습니다.
편집 2: CPU를 더 추가(-p)하면 성능이 저하됩니다.
-t 6 -p 3
- 6804.14s user 38.58s system 1040% cpu 10:57.84 total
(실제 시간의 2배, CPU 시간의 3~4배)
-t 8 -p 2
- 10573.58s user 57.47s system 1018% cpu 17:23.63 total
(실제 시간의 3배 이상, CPU 시간의 6배)
-t 4 -p 2
- 2962.38s user 28.65s system 854% cpu 5:50.01 total
(-t 4와 거의 동일)
내 생각에는 -p는 이 작업이 컴퓨터에 미치는 영향을 제한하려는 경우에만 사용해야 한다고 생각합니다. 그렇지 않으면 가능한 한 많은 프로세서를 사용하게 됩니다.
I/O는 아닌 것 같아요. 처음 5~10초 동안 3.08GB를 읽은 다음 나머지 실행(최소 5분 동안 지속) 동안 10MB 미만을 읽었습니다.
편집 3: -t 13
즉, 내 CPU가 지원하는 것보다 하나 더 많은 스레드를 사용하면 매우 이상한 결과가 생성됩니다. 93213.70s user 450.23s system 978% cpu 2:39:36.88 total
아니요, 농담이 아닙니다. CPU 시간은 50배 이상 높지만 -t 4
CPU 사용률은 거의 두 배 높습니다(978% 대 564) %), 실시간 성능이 30배 이상 향상되었습니다.
CPU 시간이 20배 이상 증가한 것과 비교하면 -t 12
CPU 사용량은 거의 동일하고 실시간도 20배 이상 증가합니다. 스레드를 하나 더 추가하면 됩니다.
여기에 뭔가 문제가 있는 것 아닌가요?
편집 4:
선택된 벤치마크 데이터
./bench -m ./models/ggml-small.en.bin -t 4
system_info: n_threads = 4 / 12 | AVX = 1 | AVX2 = 1 | AVX512 = 0 | FMA = 1 | NEON = 0 | ARM_FMA = 0 | F16C = 1 | FP16_VA = 0 | WASM_SIMD = 0 | BLAS = 1 | SSE3 = 1 | VSX = 0 |
whisper_print_timings: load time = 540.82 ms
whisper_print_timings: encode time = 3490.52 ms
whisper_print_timings: total time = 4031.40 ms
5개 스레드는 4개 스레드보다 약 8% 빠릅니다.
whisper_print_timings: load time = 547.27 ms
whisper_print_timings: encode time = 3193.27 ms
whisper_print_timings: total time = 3740.58 ms
6개 스레드는 5개 스레드보다 1% 느립니다.
whisper_print_timings: load time = 591.16 ms
whisper_print_timings: encode time = 3158.88 ms
whisper_print_timings: total time = 3750.10 ms
7개 스레드는 6개 스레드보다 15% 느립니다. 거기에서 모든 것이 내리막 길이었습니다. 내 생각에 이 작업은 하이퍼스레드 코어가 아닌 내가 가지고 있는 6개의 "실제" 코어만 사용하는 것 같습니다. 이론적으로는 6개의 스레드가 5개의 스레드보다 더 빨라야 한다고 생각하지만, 이 벤치마크를 실행하는 동안 컴퓨터가 스레드 중 하나를 중단하고 때때로 코어를 사용하는 다른 작업을 수행한다고 상상합니다.
편집 5:
-20이라는 좋은 값으로 벤치마크를 실행하면 몇 가지 흥미로운 결과가 나왔습니다(여기에는 총 시간만 나열되어 있습니다).
Threads Total time (ms) ∆ (negative is better)
4 3512 -13%
5 3510 -6%
6 3251 !! -13%
7 3962 -8%
Δ는 일반 우선순위를 갖는 동일한 수의 스레드와 비교됩니다. 우선순위가 높은 6개의 스레드는 보통 우선순위의 기본 설정보다 19% 빠릅니다.
답변1
어느 시점에서 스레드 수를 늘리면 계산 메모리가 제한되어 성능이 향상되지 않습니다. whisper.cpp
스레드를 동기화하기 위해 바쁜 루프를 사용하기 때문에 CPU 사용량이 계속 증가합니다 . 이는 더 많은 CPU 리소스를 사용하고 많은 CPU 주기를 낭비하지만 컨텍스트 전환 및 뮤텍스/조건 변수의 기타 부작용을 방지하여 대기 시간을 줄이는 데 도움이 됩니다.
이 --processors
매개변수는 CPU 프로세서를 나타내지 않습니다. 이는 whisper.cpp
오디오를 병렬로 처리하는 독립 프로세서입니다. 이 기능에 대한 자세한 내용은 여기에서 확인할 수 있습니다.
답변2
스레드 설정(-t)으로 몇 가지 테스트를 수행했습니다.
이것은 실제로 매우 좋은 생각입니다... -p 옵션에 대해 뭔가를 지정하는 한:
-p N, --processors N [1 ] 계산 중에 사용할 프로세서 수
그렇지 않으면 사용되는 프로세서 수가 기본적으로 1로 설정됩니다. 실제 이익 없이 컨텍스트 전환에 많은 시간을 낭비하게 됩니다. (유일한 이점은 IO가 다른 실행 가능한 스레드의 이점을 얻기를 기다리는 한 스레드의 시간을 활용하는 것일 수 있지만 애플리케이션이 CPU에 과도하게 바인딩되어 있음을 인정하는 것입니다...)
실제로 어떤 종류의 CPU 집약적 애플리케이션이라도 단일 프로세서에서 작업하는 스레드가 많을수록 낭비도 커집니다. 방금... 증명했습니다. ;-)
따라서 나는 다음을 권장합니다.
- 1/기본 성능 결정, 기본값 t=4;
- 2/ t=4 및 p=2이고 이점이 중요하지 않을 때까지 t를 늘립니다.
- 3/ 실행 중인 다른 애플리케이션이 손상되기 시작할 때까지 더 높은 p-값으로 2를 반복합니다.
개발자는 애플리케이션의 성능을 저하시키는 현명하지 못한 기본값을 제공하지 않을 것이라고 확신합니다.
여기에 적용된 것처럼 개발자는 애플리케이션이 상당히 IO에 묶여 있다는 점을 인정하는 것 같으므로 4:1의 t/p 비율을 권장합니다.
다음 작업 업데이트
부인 성명:Intel의 Turbo Boost 기술, 특히 Core i7이 내부적으로 어떻게 코어 주파수/오프라인 코어를 수정하고 멀티스레드 애플리케이션 성능에 미치는 영향을 결정하는지 이해할 수 없습니다.
편집 5:이 데이터 집합은 논리적 숫자를 제공합니다.
CPU 바인딩 스레드를 낮추는 데 적합한 값은 예약하는 동안 CPU가 예약되도록 허용되는 시간을 늘려 훨씬 저렴한 컨텍스트 스위치 비용으로 작업 부하를 처리합니다.
이 데이터 세트는 또한 6개의 코어만 사용되었음을 보여줍니다. 이유는 무엇입니까? 터보? HT가 비활성화되었나요? 이 중 정확히 무엇인지 알 수 있는 방법이 있다면...