mirror of
https://github.com/ggml-org/whisper.cpp.git
synced 2026-10-03 21:16:25 +02:00
whisper.android : address ARM's big.LITTLE arch by checking cpu info (#1254)
Addresses https://github.com/ggerganov/whisper.cpp/issues/1248
This commit is contained in:
@@ -18,7 +18,9 @@ class WhisperContext private constructor(private var ptr: Long) {
|
||||
|
||||
suspend fun transcribeData(data: FloatArray): String = withContext(scope.coroutineContext) {
|
||||
require(ptr != 0L)
|
||||
WhisperLib.fullTranscribe(ptr, data)
|
||||
val numThreads = WhisperCpuConfig.preferredThreadCount
|
||||
Log.d(LOG_TAG, "Selecting $numThreads threads")
|
||||
WhisperLib.fullTranscribe(ptr, numThreads, data)
|
||||
val textCount = WhisperLib.getTextSegmentCount(ptr)
|
||||
return@withContext buildString {
|
||||
for (i in 0 until textCount) {
|
||||
@@ -126,7 +128,7 @@ private class WhisperLib {
|
||||
external fun initContextFromAsset(assetManager: AssetManager, assetPath: String): Long
|
||||
external fun initContext(modelPath: String): Long
|
||||
external fun freeContext(contextPtr: Long)
|
||||
external fun fullTranscribe(contextPtr: Long, audioData: FloatArray)
|
||||
external fun fullTranscribe(contextPtr: Long, numThreads: Int, audioData: FloatArray)
|
||||
external fun getTextSegmentCount(contextPtr: Long): Int
|
||||
external fun getTextSegment(contextPtr: Long, index: Int): String
|
||||
external fun getSystemInfo(): String
|
||||
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
package com.whispercppdemo.whisper
|
||||
|
||||
import android.util.Log
|
||||
import java.io.BufferedReader
|
||||
import java.io.FileReader
|
||||
|
||||
object WhisperCpuConfig {
|
||||
val preferredThreadCount: Int
|
||||
// Always use at least 2 threads:
|
||||
get() = CpuInfo.getHighPerfCpuCount().coerceAtLeast(2)
|
||||
}
|
||||
|
||||
private class CpuInfo(private val lines: List<String>) {
|
||||
private fun getHighPerfCpuCount(): Int = try {
|
||||
getHighPerfCpuCountByFrequencies()
|
||||
} catch (e: Exception) {
|
||||
Log.d(LOG_TAG, "Couldn't read CPU frequencies", e)
|
||||
getHighPerfCpuCountByVariant()
|
||||
}
|
||||
|
||||
private fun getHighPerfCpuCountByFrequencies(): Int =
|
||||
getCpuValues(property = "processor") { getMaxCpuFrequency(it.toInt()) }
|
||||
.also { Log.d(LOG_TAG, "Binned cpu frequencies (frequency, count): ${it.binnedValues()}") }
|
||||
.countDroppingMin()
|
||||
|
||||
private fun getHighPerfCpuCountByVariant(): Int =
|
||||
getCpuValues(property = "CPU variant") { it.substringAfter("0x").toInt(radix = 16) }
|
||||
.also { Log.d(LOG_TAG, "Binned cpu variants (variant, count): ${it.binnedValues()}") }
|
||||
.countKeepingMin()
|
||||
|
||||
private fun List<Int>.binnedValues() = groupingBy { it }.eachCount()
|
||||
|
||||
private fun getCpuValues(property: String, mapper: (String) -> Int) = lines
|
||||
.asSequence()
|
||||
.filter { it.startsWith(property) }
|
||||
.map { mapper(it.substringAfter(':').trim()) }
|
||||
.sorted()
|
||||
.toList()
|
||||
|
||||
|
||||
private fun List<Int>.countDroppingMin(): Int {
|
||||
val min = min()
|
||||
return count { it > min }
|
||||
}
|
||||
|
||||
private fun List<Int>.countKeepingMin(): Int {
|
||||
val min = min()
|
||||
return count { it == min }
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val LOG_TAG = "WhisperCpuConfig"
|
||||
|
||||
fun getHighPerfCpuCount(): Int = try {
|
||||
readCpuInfo().getHighPerfCpuCount()
|
||||
} catch (e: Exception) {
|
||||
Log.d(LOG_TAG, "Couldn't read CPU info", e)
|
||||
// Our best guess -- just return the # of CPUs minus 4.
|
||||
(Runtime.getRuntime().availableProcessors() - 4).coerceAtLeast(0)
|
||||
}
|
||||
|
||||
private fun readCpuInfo() = CpuInfo(
|
||||
BufferedReader(FileReader("/proc/cpuinfo"))
|
||||
.useLines { it.toList() }
|
||||
)
|
||||
|
||||
private fun getMaxCpuFrequency(cpuIndex: Int): Int {
|
||||
val path = "/sys/devices/system/cpu/cpu${cpuIndex}/cpufreq/cpuinfo_max_freq"
|
||||
val maxFreq = BufferedReader(FileReader(path)).use { it.readLine() }
|
||||
return maxFreq.toInt()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user