mirror of
https://github.com/espressif/esp-sr.git
synced 2025-09-15 15:28:44 +08:00
feat(model): modify model loader to reduce model bin size for esp32
This commit is contained in:
parent
34e264eb5a
commit
6b21fdf970
@ -2,6 +2,7 @@ if(IDF_TARGET STREQUAL "esp32")
|
||||
set(COMPONENT_ADD_INCLUDEDIRS
|
||||
esp-tts/esp_tts_chinese/include
|
||||
include/esp32
|
||||
src/include
|
||||
)
|
||||
set(COMPONENT_SRCS
|
||||
src/esp_mn_speech_commands.c
|
||||
@ -40,6 +41,7 @@ elseif(${IDF_TARGET} STREQUAL "esp32s2")
|
||||
set(COMPONENT_ADD_INCLUDEDIRS
|
||||
esp-tts/esp_tts_chinese/include
|
||||
include/esp32
|
||||
src/include
|
||||
)
|
||||
set(COMPONENT_SRCS
|
||||
src/esp_process_sdkconfig.c
|
||||
@ -62,6 +64,7 @@ elseif(${IDF_TARGET} STREQUAL "esp32s3")
|
||||
set(COMPONENT_ADD_INCLUDEDIRS
|
||||
esp-tts/esp_tts_chinese/include
|
||||
include/esp32s3
|
||||
src/include
|
||||
)
|
||||
set(COMPONENT_SRCS
|
||||
src/esp_mn_speech_commands.c
|
||||
|
||||
@ -1,79 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char **model_name; // the name of models, like "wn9_hilexin"(wakenet9, hilexin), "mn5_en"(multinet5, english)
|
||||
char *partition_label; // partition label used to save the files of model
|
||||
int num; // the number of models
|
||||
} srmodel_list_t;
|
||||
|
||||
#define MODEL_NAME_MAX_LENGTH 64
|
||||
|
||||
/**
|
||||
* @brief Return all avaliable models in spiffs or selected in Kconfig.
|
||||
*
|
||||
* @param partition_label The spiffs label defined in your partition file used to save models.
|
||||
*
|
||||
* @return all avaliable models in spiffs,save as srmodel_list_t.
|
||||
*/
|
||||
srmodel_list_t* esp_srmodel_init(const char* partition_label);
|
||||
|
||||
/**
|
||||
* @brief Free srmodel_list_t and unregister SPIFFS filesystem if open SPIFFS filesystem.
|
||||
*
|
||||
* @param models The srmodel_list_t point allocated by esp_srmodel_init function.
|
||||
*
|
||||
* @return all avaliable models in spiffs,save as srmodel_list_t.
|
||||
*/
|
||||
void esp_srmodel_deinit(srmodel_list_t *models);
|
||||
|
||||
/**
|
||||
* @brief Return the first model name containing the specified keywords
|
||||
* If keyword is NULL, we will ignore the keyword.
|
||||
*
|
||||
* @param models The srmodel_list_t point allocated by esp_srmodel_init function.
|
||||
* @param keyword1 The specified keyword1 , like ESP_WN_PREDIX(the prefix of wakenet),
|
||||
* ESP_MN_PREFIX(the prefix of multinet),
|
||||
*
|
||||
* @param keyword2 The specified keyword2, like ESP_MN_ENGLISH(the english multinet)
|
||||
* ESP_MN_CHINESE(the chinese multinet)
|
||||
* "alexa" (the "alexa" wakenet)
|
||||
* @return return model name if can find one model name containing the keywords otherwise return NULL.
|
||||
*/
|
||||
char *esp_srmodel_filter(srmodel_list_t *models, const char *keyword1, const char *keyword2);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Check whether the specified model name exists or not.
|
||||
*
|
||||
* @param models The srmodel_list_t point allocated by esp_srmodel_init function.
|
||||
* @param model_name The specified model name
|
||||
* @return return index in models if model name exists otherwise return -1
|
||||
*/
|
||||
int esp_srmodel_exists(srmodel_list_t *models, char *model_name);
|
||||
|
||||
/**
|
||||
* @brief Initialize and mount SPIFFS filesystem, return all avaliable models in spiffs.
|
||||
*
|
||||
* @param partition_label The spiffs label defined in your partition file used to save models.
|
||||
*
|
||||
* @return all avaliable models in spiffs,save as srmodel_list_t.
|
||||
*/
|
||||
srmodel_list_t *srmodel_spiffs_init(const char* partition_label);
|
||||
|
||||
/**
|
||||
* @brief unregister SPIFFS filesystem and free srmodel_list_t.
|
||||
*
|
||||
* @param models The srmodel_list_t point allocated by srmodel_spiffs_init function.
|
||||
*
|
||||
* @return all avaliable models in spiffs,save as srmodel_list_t.
|
||||
*/
|
||||
void srmodel_spiffs_deinit(srmodel_list_t *models);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Return base path of srmodel spiffs
|
||||
*
|
||||
* @return the base path od srmodel spiffs
|
||||
*/
|
||||
char *get_model_base_path(void);
|
||||
@ -1,158 +0,0 @@
|
||||
// Copyright 2015-2022 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#pragma once
|
||||
#include "esp_err.h"
|
||||
#include "esp_mn_iface.h"
|
||||
|
||||
/*
|
||||
esp_mn_node_t is a singly linked list which is used to manage speech commands.
|
||||
It is easy to add one speech command into linked list and remove one speech command from linked list.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initialze the speech commands singly linked list.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_NO_MEM No memory
|
||||
* - ESP_ERR_INVALID_STATE The Speech Commands link has been initialized
|
||||
*/
|
||||
esp_err_t esp_mn_commands_alloc(void);
|
||||
|
||||
/**
|
||||
* @brief Clear the speech commands linked list and free root node.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_STATE The Speech Commands link has not been initialized
|
||||
*/
|
||||
esp_err_t esp_mn_commands_free(void);
|
||||
|
||||
/**
|
||||
* @brief Add one speech commands with phoneme string and command ID
|
||||
*
|
||||
* @param command_id The command ID
|
||||
* @param phoneme_string The phoneme string of the speech commands
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_STATE Fail
|
||||
*/
|
||||
esp_err_t esp_mn_commands_add(int command_id, char *phoneme_string);
|
||||
|
||||
/**
|
||||
* @brief Modify one speech commands with new phoneme string
|
||||
*
|
||||
* @param old_phoneme_string The old phoneme string of the speech commands
|
||||
* @param new_phoneme_string The new phoneme string of the speech commands
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_STATE Fail
|
||||
*/
|
||||
esp_err_t esp_mn_commands_modify(char *old_phoneme_string, char *new_phoneme_string);
|
||||
|
||||
/**
|
||||
* @brief Remove one speech commands by phoneme string
|
||||
*
|
||||
* @param phoneme_string The phoneme string of the speech commands
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_STATE Fail
|
||||
*/
|
||||
esp_err_t esp_mn_commands_remove(char *phoneme_string);
|
||||
|
||||
/**
|
||||
* @brief Clear all speech commands in linked list
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_STATE Fail
|
||||
*/
|
||||
esp_err_t esp_mn_commands_clear(void);
|
||||
|
||||
/**
|
||||
* @brief Get phrase from index, which is the depth from the phrase node to root node
|
||||
*
|
||||
* @Warning: The first phrase index is 0, the second phrase index is 1, and so on.
|
||||
*
|
||||
* @return
|
||||
* - esp_mn_phrase_t* Success
|
||||
* - NULL Fail
|
||||
*/
|
||||
esp_mn_phrase_t *esp_mn_commands_get_from_index(int index);
|
||||
|
||||
/**
|
||||
* @brief Get phrase from phoneme string
|
||||
*
|
||||
* @return
|
||||
* - esp_mn_phrase_t* Success
|
||||
* - NULL Fail
|
||||
*/
|
||||
esp_mn_phrase_t *esp_mn_commands_get_from_string(const char *phoneme_string);
|
||||
|
||||
/**
|
||||
* @brief Update the speech commands of MultiNet
|
||||
*
|
||||
* @Warning: Must be used after [add/remove/modify/clear] function,
|
||||
* otherwise the language model of multinet can not be updated.
|
||||
*
|
||||
* @param multinet The multinet handle
|
||||
* @param model_data The model object to query
|
||||
*
|
||||
* @return
|
||||
* - NULL Success
|
||||
* - others The list of error phrase which can not be parsed by multinet.
|
||||
*/
|
||||
esp_mn_error_t *esp_mn_commands_update(const esp_mn_iface_t *multinet, const model_iface_data_t *model_data);
|
||||
|
||||
/**
|
||||
* @brief Print the MultiNet Speech Commands.
|
||||
*/
|
||||
void esp_mn_print_commands(void);
|
||||
|
||||
/**
|
||||
* @brief Initialze the esp_mn_phrase_t struct by command id and phoneme string .
|
||||
*
|
||||
* @return the pointer of esp_mn_phrase_t
|
||||
*/
|
||||
esp_mn_phrase_t *esp_mn_phrase_alloc(int command_id, char *phoneme_string);
|
||||
|
||||
/**
|
||||
* @brief Free esp_mn_phrase_t pointer.
|
||||
*
|
||||
* @param phrase The esp_mn_phrase_t pointer
|
||||
*/
|
||||
void esp_mn_phrase_free(esp_mn_phrase_t *phrase);
|
||||
|
||||
/**
|
||||
* @brief Initialze the esp_mn_node_t struct by esp_mn_phrase_t pointer.
|
||||
*
|
||||
* @return the pointer of esp_mn_node_t
|
||||
*/
|
||||
esp_mn_node_t *esp_mn_node_alloc(esp_mn_phrase_t *phrase);
|
||||
|
||||
/**
|
||||
* @brief Free esp_mn_node_t pointer.
|
||||
*
|
||||
* @param node The esp_mn_node_free pointer
|
||||
*/
|
||||
void esp_mn_node_free(esp_mn_node_t *node);
|
||||
|
||||
/**
|
||||
* @brief Print phrase linked list.
|
||||
*/
|
||||
void esp_mn_commands_print(void);
|
||||
@ -1,23 +0,0 @@
|
||||
#pragma once
|
||||
#include "esp_err.h"
|
||||
#include "esp_mn_iface.h"
|
||||
|
||||
/**
|
||||
* @brief Check chip config to ensure optimum performance
|
||||
*/
|
||||
void check_chip_config(void);
|
||||
|
||||
/**
|
||||
* @brief Update the speech commands of MultiNet by menuconfig
|
||||
*
|
||||
* @param multinet The multinet handle
|
||||
*
|
||||
* @param model_data The model object to query
|
||||
*
|
||||
* @param langugae The language of MultiNet
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_STATE Fail
|
||||
*/
|
||||
esp_err_t esp_mn_commands_update_from_sdkconfig(esp_mn_iface_t *multinet, const model_iface_data_t *model_data);
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -876,7 +876,7 @@ char *get_id_name_en(int i)
|
||||
#endif
|
||||
}
|
||||
|
||||
esp_err_t esp_mn_commands_update_from_sdkconfig(esp_mn_iface_t *multinet, const model_iface_data_t *model_data)
|
||||
esp_mn_error_t* esp_mn_commands_update_from_sdkconfig(esp_mn_iface_t *multinet, const model_iface_data_t *model_data)
|
||||
{
|
||||
esp_mn_commands_alloc();
|
||||
int total_phrase_num = 0;
|
||||
@ -902,7 +902,6 @@ esp_err_t esp_mn_commands_update_from_sdkconfig(esp_mn_iface_t *multinet, const
|
||||
|
||||
char *token = strtok(command_str_temp, ",");
|
||||
while (token != NULL) {
|
||||
int len = strlen(token);
|
||||
if (total_phrase_num > ESP_MN_MAX_PHRASE_NUM) {
|
||||
ESP_LOGE(TAG, "The number of speech commands phrase must less than ESP_MN_MAX_PHRASE_NUM");
|
||||
free(command_str_temp);
|
||||
|
||||
@ -20,4 +20,4 @@ void check_chip_config(void);
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_STATE Fail
|
||||
*/
|
||||
esp_err_t esp_mn_commands_update_from_sdkconfig(esp_mn_iface_t *multinet, const model_iface_data_t *model_data);
|
||||
esp_mn_error_t* esp_mn_commands_update_from_sdkconfig(esp_mn_iface_t *multinet, const model_iface_data_t *model_data);
|
||||
@ -76,4 +76,19 @@ void srmodel_spiffs_deinit(srmodel_list_t *models);
|
||||
*
|
||||
* @return the base path od srmodel spiffs
|
||||
*/
|
||||
char *get_model_base_path(void);
|
||||
char *get_model_base_path(void);
|
||||
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
#include "dl_lib_coefgetter_if.h"
|
||||
/**
|
||||
* @brief Return model_coeff_getter_t pointer base on model_name
|
||||
*
|
||||
* @warning Just support ESP32 to load old wakenet
|
||||
*
|
||||
* @param model_name The model name
|
||||
*
|
||||
* @return model_coeff_getter_t pointer or NULL
|
||||
*/
|
||||
model_coeff_getter_t* srmodel_get_model_coeff(char *model_name);
|
||||
#endif
|
||||
@ -79,8 +79,7 @@ srmodel_list_t *read_models_form_spiffs(esp_vfs_spiffs_conf_t *conf)
|
||||
|
||||
srmodel_list_t* srmodel_spiffs_init(const char *partition_label)
|
||||
{
|
||||
printf(" \n");
|
||||
ESP_LOGI(TAG, "Initializing models from SPIFFS, partition label: %s", partition_label);
|
||||
ESP_LOGI(TAG, "\nInitializing models from SPIFFS, partition label: %s\n", partition_label);
|
||||
|
||||
esp_vfs_spiffs_conf_t conf = {
|
||||
.base_path = SRMODE_BASE_PATH,
|
||||
@ -185,6 +184,12 @@ void srmodel_config_deinit(srmodel_list_t *models)
|
||||
}
|
||||
}
|
||||
|
||||
model_coeff_getter_t* srmodel_get_model_coeff(char *model_name)
|
||||
{
|
||||
model_coeff_getter_t *gettercb = &WAKENET_COEFF;
|
||||
return gettercb;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
char *get_model_base_path(void)
|
||||
@ -200,7 +205,7 @@ int set_model_base_path(const char *base_path)
|
||||
return 1;
|
||||
}
|
||||
|
||||
char* join_path(char* dirname, char *filename)
|
||||
char* _join_path_(const char* dirname, const char *filename)
|
||||
{
|
||||
if (dirname == NULL || filename == NULL)
|
||||
return NULL;
|
||||
@ -223,8 +228,8 @@ srmodel_list_t* srmodel_sdcard_init(const char *base_path)
|
||||
{
|
||||
printf("Initializing models from path: %s\n", base_path);
|
||||
set_model_base_path(base_path);
|
||||
struct dirent *ret, *sub_ret;
|
||||
DIR *dir, *sub_dir;
|
||||
struct dirent *ret;
|
||||
DIR *dir;
|
||||
dir = opendir(base_path);
|
||||
srmodel_list_t *models = NULL;
|
||||
int model_num = 0;
|
||||
@ -238,8 +243,8 @@ srmodel_list_t* srmodel_sdcard_init(const char *base_path)
|
||||
{ // NULL if reach the end of directory
|
||||
|
||||
if (ret->d_type == DT_DIR) { // if d_type is directory
|
||||
char *sub_path = join_path(base_path, ret->d_name);
|
||||
char *info_file = join_path(sub_path, "_MODEL_INFO_");
|
||||
char *sub_path = _join_path_(base_path, ret->d_name);
|
||||
char *info_file = _join_path_(sub_path, "_MODEL_INFO_");
|
||||
fp = fopen(info_file, "r");
|
||||
if (fp != NULL) {
|
||||
model_num ++; // If _MODLE_INFO_ file exists, model_num ++
|
||||
@ -271,8 +276,8 @@ srmodel_list_t* srmodel_sdcard_init(const char *base_path)
|
||||
{ // NULL if reach the end of directory
|
||||
|
||||
if (ret->d_type == DT_DIR) { // if d_type is directory
|
||||
char *sub_path = join_path(base_path, ret->d_name);
|
||||
char *info_file = join_path(sub_path, "_MODEL_INFO_");
|
||||
char *sub_path = _join_path_(base_path, ret->d_name);
|
||||
char *info_file = _join_path_(sub_path, "_MODEL_INFO_");
|
||||
fp = fopen(info_file, "r");
|
||||
if (fp != NULL) {
|
||||
memcpy(models->model_name[idx], ret->d_name, strlen(ret->d_name));
|
||||
@ -337,7 +342,7 @@ void esp_srmodel_deinit(srmodel_list_t *models)
|
||||
char *_esp_strstr_(const char *haystack, const char *needle)
|
||||
{
|
||||
if (needle == NULL) return haystack;
|
||||
else return strstr(haystack, needle);
|
||||
else return (char *)strstr(haystack, needle);
|
||||
}
|
||||
|
||||
char *esp_srmodel_filter(srmodel_list_t *models, const char *keyword1, const char *keyword2)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user