fix: 修复 Windows Qt5.12 MinGW 编译错误
- std::unordered_map 替换为 QHash(旧版 GCC 7.3.0 不支持 QString 的 std::hash) - 涉及文件: whisper_tokenizer.h/cpp, sense_voice_tokenizer.h/cpp - STTEngine::Impl 的 loadInWorker 和 mutex 移出 HAVE_ONNXRUNTIME 条件编译块 - loadModelSync/loadModelAsync 添加 HAVE_ONNXRUNTIME 保护 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
50b6a5daea
commit
a56f273c45
@ -41,7 +41,7 @@ bool SenseVoiceTokenizer::load(const QString& tokensPath) {
|
||||
}
|
||||
|
||||
LOG_INFO(kTag, QString("词表已加载: %1 个词条 (%2)").arg(lineCount).arg(tokensPath));
|
||||
return !tokenToString_.empty();
|
||||
return !tokenToString_.isEmpty();
|
||||
}
|
||||
|
||||
QString SenseVoiceTokenizer::decode(const std::vector<int>& tokens) const {
|
||||
@ -56,7 +56,7 @@ QString SenseVoiceTokenizer::decode(const std::vector<int>& tokens) const {
|
||||
|
||||
auto it = tokenToString_.find(token);
|
||||
if (it != tokenToString_.end()) {
|
||||
QString decoded = decodeBPE(it->second);
|
||||
QString decoded = decodeBPE(it.value());
|
||||
// 过滤 SenseVoice 特殊标签: <|zh|>, <|speech|>, <|NEUTRAL|> 等
|
||||
if (decoded.startsWith("<|") && decoded.endsWith("|>")) {
|
||||
continue;
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QHash>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace impress {
|
||||
|
||||
@ -24,10 +23,10 @@ public:
|
||||
QString decode(const std::vector<int>& tokens) const;
|
||||
|
||||
/** @brief 是否已加载 */
|
||||
bool isLoaded() const { return !tokenToString_.empty(); }
|
||||
bool isLoaded() const { return !tokenToString_.isEmpty(); }
|
||||
|
||||
/** @brief 词表大小 */
|
||||
int vocabSize() const { return static_cast<int>(tokenToString_.size()); }
|
||||
int vocabSize() const { return tokenToString_.size(); }
|
||||
|
||||
// 特殊 token
|
||||
static constexpr int kTokenBlank = 0; // CTC blank / <unk>
|
||||
@ -35,7 +34,7 @@ public:
|
||||
static constexpr int kTokenEOS = 2; // </s>
|
||||
|
||||
private:
|
||||
std::unordered_map<int, QString> tokenToString_;
|
||||
QHash<int, QString> tokenToString_;
|
||||
QString decodeBPE(const QString& token) const;
|
||||
};
|
||||
|
||||
|
||||
@ -116,9 +116,9 @@ struct STTEngine::Impl {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
QMutex mutex;
|
||||
#endif
|
||||
};
|
||||
|
||||
STTEngine::STTEngine(QObject* parent)
|
||||
@ -139,6 +139,7 @@ bool STTEngine::loadModelSync(const QString& modelPath,
|
||||
unloadModel();
|
||||
}
|
||||
|
||||
#ifdef HAVE_ONNXRUNTIME
|
||||
QString errorMsg;
|
||||
bool success = impl_->loadInWorker(modelPath, device, numThreads, errorMsg);
|
||||
loaded_ = success;
|
||||
@ -150,6 +151,11 @@ bool STTEngine::loadModelSync(const QString& modelPath,
|
||||
emit error(errorMsg);
|
||||
}
|
||||
return success;
|
||||
#else
|
||||
(void)modelPath; (void)device; (void)numThreads;
|
||||
LOG_ERROR(kTag, "ONNX Runtime 未编译启用");
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void STTEngine::loadModelAsync(const QString& modelPath,
|
||||
@ -161,6 +167,7 @@ void STTEngine::loadModelAsync(const QString& modelPath,
|
||||
unloadModel();
|
||||
}
|
||||
|
||||
#ifdef HAVE_ONNXRUNTIME
|
||||
LOG_INFO(kTag, QString("异步加载模型: %1").arg(modelPath));
|
||||
|
||||
QFuture<void> future = QtConcurrent::run([this, modelPath, device, numThreads]() {
|
||||
@ -177,6 +184,10 @@ void STTEngine::loadModelAsync(const QString& modelPath,
|
||||
}
|
||||
}, Qt::QueuedConnection);
|
||||
});
|
||||
#else
|
||||
(void)modelPath; (void)device; (void)numThreads;
|
||||
LOG_ERROR(kTag, "ONNX Runtime 未编译启用");
|
||||
#endif
|
||||
}
|
||||
|
||||
void STTEngine::unloadModel() {
|
||||
|
||||
@ -45,7 +45,7 @@ bool WhisperTokenizer::loadVocabulary(const QString& vocabPath) {
|
||||
}
|
||||
|
||||
LOG_INFO(kTag, QString("词表已加载: %1 个词条 (文件: %2)").arg(lineCount).arg(vocabPath));
|
||||
return !tokenToString_.empty();
|
||||
return !tokenToString_.isEmpty();
|
||||
}
|
||||
|
||||
QString WhisperTokenizer::decode(const std::vector<int>& tokens) const {
|
||||
@ -55,7 +55,7 @@ QString WhisperTokenizer::decode(const std::vector<int>& tokens) const {
|
||||
|
||||
auto it = tokenToString_.find(token);
|
||||
if (it != tokenToString_.end()) {
|
||||
QString decoded = decodeBytePair(it->second);
|
||||
QString decoded = decodeBytePair(it.value());
|
||||
result += decoded;
|
||||
} else {
|
||||
result += QString("<|token:%1|>").arg(token);
|
||||
@ -71,7 +71,7 @@ std::vector<int> WhisperTokenizer::encode(const QString& text) const {
|
||||
QString ch = text.mid(i, 1);
|
||||
auto it = stringToToken_.find(ch);
|
||||
if (it != stringToToken_.end()) {
|
||||
tokens.push_back(it->second);
|
||||
tokens.push_back(it.value());
|
||||
}
|
||||
}
|
||||
return tokens;
|
||||
@ -86,13 +86,13 @@ QString WhisperTokenizer::decodeBytePair(const QString& text) const {
|
||||
}
|
||||
|
||||
int WhisperTokenizer::languageTokenId(const QString& langCode) {
|
||||
static const std::unordered_map<QString, int> langMap = {
|
||||
static const QHash<QString, int> langMap = {
|
||||
{"zh", 50260}, {"en", 50259}, {"ja", 50261}, {"ko", 50262},
|
||||
{"fr", 50265}, {"de", 50266}, {"es", 50267}, {"ru", 50268},
|
||||
{"pt", 50269}, {"it", 50270}, {"auto", 50359}
|
||||
};
|
||||
auto it = langMap.find(langCode);
|
||||
return it != langMap.end() ? it->second : 50259; // 默认英语
|
||||
return it != langMap.end() ? it.value() : 50259; // 默认英语
|
||||
}
|
||||
|
||||
bool WhisperTokenizer::isSpecialToken(int token) {
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QHash>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <optional>
|
||||
|
||||
namespace impress {
|
||||
@ -28,10 +27,10 @@ public:
|
||||
std::vector<int> encode(const QString& text) const;
|
||||
|
||||
/** @brief 是否已加载词表 */
|
||||
bool isLoaded() const { return !tokenToString_.empty(); }
|
||||
bool isLoaded() const { return !tokenToString_.isEmpty(); }
|
||||
|
||||
/** @brief 词表大小 */
|
||||
int vocabSize() const { return static_cast<int>(tokenToString_.size()); }
|
||||
int vocabSize() const { return tokenToString_.size(); }
|
||||
|
||||
// Whisper 特殊 token
|
||||
static constexpr int kTokenEndOfText = 50257;
|
||||
@ -49,8 +48,8 @@ public:
|
||||
static bool isSpecialToken(int token);
|
||||
|
||||
private:
|
||||
std::unordered_map<int, QString> tokenToString_;
|
||||
std::unordered_map<QString, int> stringToToken_;
|
||||
QHash<int, QString> tokenToString_;
|
||||
QHash<QString, int> stringToToken_;
|
||||
|
||||
QString decodeBytePair(const QString& text) const;
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user