Skip to content

Commit d2e53e9

Browse files
authored
Merge pull request #36 from mikeoliphant/nam_a2
NAM a2 support
2 parents 14fb7bf + 9ea05d9 commit d2e53e9

7 files changed

Lines changed: 2229 additions & 59 deletions

File tree

NeuralAudio/CMakeLists.txt

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,20 @@ else()
1111
message(STATUS "NOT Building static RTNeural models")
1212
endif()
1313

14-
option(BUILD_NAMCORE "Build NAM Core" OFF)
14+
option(BUILD_NAMCORE "Build NAM Core" ON)
1515
if(BUILD_NAMCORE)
1616
message(STATUS "Building NAM Core implementation")
1717
add_definitions(-DBUILD_NAMCORE)
1818
else()
1919
message(STATUS "NOT Building NAM Core implementation")
2020
endif()
2121

22+
option(NAM_USE_INLINE_GEMM "Use inline matrix multiplications in NAM Core" OFF)
23+
if(NAM_USE_INLINE_GEMM)
24+
message(STATUS "Using NAM Core inline matrix multiplications")
25+
add_definitions(-DNAM_USE_INLINE_GEMM)
26+
else()
27+
message(STATUS "NOT Using NAM Core inline matrix multiplications")
2228
option(BUILD_INTERNAL_STATIC_WAVENET "Build Internal static WaveNet models" ON)
2329
if(BUILD_INTERNAL_STATIC_WAVENET)
2430
message(STATUS "Building Internal static WaveNet models")
@@ -77,7 +83,16 @@ set(SOURCES
7783
if(BUILD_NAMCORE)
7884
set(NAM_SOURCES ../deps/NeuralAmpModelerCore/NAM/activations.h
7985
../deps/NeuralAmpModelerCore/NAM/activations.cpp
86+
../deps/NeuralAmpModelerCore/NAM/conv1d.cpp
87+
../deps/NeuralAmpModelerCore/NAM/conv1d.h
88+
../deps/NeuralAmpModelerCore/NAM/film.h
89+
../deps/NeuralAmpModelerCore/NAM/gating_activations.h
90+
../deps/NeuralAmpModelerCore/NAM/get_dsp.h
91+
../deps/NeuralAmpModelerCore/NAM/get_dsp.cpp
8092
../deps/NeuralAmpModelerCore/NAM/lstm.h
93+
../deps/NeuralAmpModelerCore/NAM/registry.h
94+
../deps/NeuralAmpModelerCore/NAM/ring_buffer.h
95+
../deps/NeuralAmpModelerCore/NAM/ring_buffer.cpp
8196
../deps/NeuralAmpModelerCore/NAM/lstm.cpp
8297
../deps/NeuralAmpModelerCore/NAM/dsp.h
8398
../deps/NeuralAmpModelerCore/NAM/dsp.cpp
@@ -92,7 +107,7 @@ set(RTNEURAL_WN_SOURCES ../deps/RTNeural-NAM/wavenet/wavenet_layer.hpp
92107
../deps/RTNeural-NAM/wavenet/arena.hpp)
93108
endif()
94109

95-
add_library(NeuralAudio STATIC ${SOURCES} ${NAM_SOURCES} ${RTNEURAL_WN_SOURCES})
110+
add_library(NeuralAudio OBJECT ${SOURCES} ${NAM_SOURCES} ${RTNEURAL_WN_SOURCES})
96111

97112
target_include_directories(NeuralAudio PUBLIC ..)
98113
target_include_directories(NeuralAudio SYSTEM PRIVATE ../deps/NeuralAmpModelerCore)

NeuralAudio/NAMModel.h

Lines changed: 4 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
#include "NeuralModel.h"
44
#include <NAM/activations.h>
5+
#include <NAM/get_dsp.h>
56
#include <NAM/dsp.h>
6-
#include <NAM/lstm.h>
7-
#include <NAM/wavenet.h>
7+
#include <NAM/registry.h>
88

99
namespace NeuralAudio
1010
{
@@ -34,46 +34,14 @@ namespace NeuralAudio
3434

3535
ReadNAMConfig(modelJson);
3636

37-
std::string arch = modelJson.at("architecture");
38-
39-
nlohmann::json config = modelJson.at("config");
40-
41-
std::vector<float> weights = modelJson.at("weights");
42-
43-
if (arch == "WaveNet")
44-
{
45-
std::vector<nam::wavenet::LayerArrayParams> layer_array_params;
46-
47-
for (size_t i = 0; i < config.at("layers").size(); i++)
48-
{
49-
nlohmann::json layerConfig = config.at("layers").at(i);
50-
51-
layer_array_params.push_back(
52-
nam::wavenet::LayerArrayParams(layerConfig.at("input_size"), layerConfig.at("condition_size"), layerConfig.at("head_size"),
53-
layerConfig.at("channels"), layerConfig.at("kernel_size"), layerConfig.at("dilations"),
54-
layerConfig.at("activation"), layerConfig.at("gated"), layerConfig.at("head_bias")));
55-
}
56-
57-
const bool with_head = !config.at("head").is_null();
58-
const float head_scale = config.at("head_scale");
59-
60-
namModel = std::make_unique<nam::wavenet::WaveNet>(layer_array_params, head_scale, with_head, weights, sampleRate);
61-
}
62-
else if (arch == "LSTM")
63-
{
64-
const int num_layers = config.at("num_layers");
65-
const int input_size = config.at("input_size");
66-
const int hidden_size = config.at("hidden_size");
67-
68-
namModel = std::make_unique<nam::lstm::LSTM>(num_layers, input_size, hidden_size, weights, sampleRate);
69-
}
37+
namModel = nam::get_dsp(modelJson);
7038

7139
return true;
7240
}
7341

7442
void Process(float* input, float* output, size_t numSamples)
7543
{
76-
namModel->process(input, output, (int)numSamples);
44+
namModel->process(&input, &output, (int)numSamples);
7745
}
7846

7947
void Prewarm()

NeuralAudio/NeuralModel.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,17 @@ namespace NeuralAudio
126126
return CreateFromStream(jsonStream, modelPath.extension());
127127
}
128128

129+
bool NAMIsA2(std::string version)
130+
{
131+
int major = 0, minor = 0, patch = 0;
132+
char dot;
133+
std::stringstream ss(version);
134+
135+
ss >> major >> dot >> minor >> dot >> patch;
136+
137+
return (major > 0) || (minor > 5) || ((minor == 5) && (patch > 4));
138+
}
139+
129140
NeuralModel* NeuralModel::CreateFromStream(std::basic_istream<char>& jsonStream, std::filesystem::path extension)
130141
{
131142
EnsureModelDefsAreLoaded();
@@ -137,10 +148,10 @@ namespace NeuralAudio
137148

138149
if (extension == ".nam")
139150
{
140-
std::string arch = modelJson.at("architecture");
141-
142151
#ifdef BUILD_NAMCORE
143-
if (wavenetLoadMode == EModelLoadMode::NAMCore)
152+
std::string version = modelJson.at("version");
153+
154+
if ((wavenetLoadMode == EModelLoadMode::NAMCore) || NAMIsA2(version))
144155
{
145156
NAMModel* model = new NAMModel;
146157

@@ -150,12 +161,13 @@ namespace NeuralAudio
150161
}
151162
#endif
152163

164+
std::string arch = modelJson.at("architecture");
165+
nlohmann::json config = modelJson.at("config");
166+
153167
if (newModel == nullptr)
154168
{
155169
if (arch == "WaveNet")
156170
{
157-
nlohmann::json config = modelJson.at("config");
158-
159171
if (config.at("layers").size() == 2)
160172
{
161173
nlohmann::json firstLayerConfig = config.at("layers").at(0);
@@ -219,8 +231,6 @@ namespace NeuralAudio
219231
}
220232
else if (arch == "LSTM")
221233
{
222-
nlohmann::json config = modelJson.at("config");
223-
224234
#ifdef BUILD_STATIC_RTNEURAL
225235
if (lstmLoadMode == EModelLoadMode::RTNeural)
226236
{

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ Note - you'll have to change the Visual Studio version if you are using a differ
130130

131131
```-DBUILD_NAMCORE=ON|OFF```: Support loading models using the NAM Core implemenations.
132132

133+
```-DNAM_USE_INLINE_GEMM=ON```: Enable use of inline matrix multiplication in NAM Core.
134+
133135
```-DBUILD_STATIC_RTNEURAL=ON|OFF```: Build static RTNeural model architectures (slower compile, larger size - only use if you plan on forcing RTNeural model loading).
134136

135137
```-DBUILD_INTERNAL_STATIC_WAVENET=ON|OFF```: Build internal static WaveNet model architectures (faster internal WaveNet, but slower compile, larger size).

Utils/ModelTest/ModelTest.cpp

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ NeuralModel* LoadModel(std::filesystem::path modelPath, EModelLoadMode loadMode)
1212
NeuralModel::SetWaveNetLoadMode(loadMode);
1313
NeuralModel::SetLSTMLoadMode(loadMode);
1414

15+
if (!std::filesystem::exists(modelPath))
16+
{
17+
std::cout << "Model file does not exist: " << modelPath << std::endl;
18+
19+
return nullptr;
20+
}
21+
1522
try
1623
{
1724
auto model = NeuralAudio::NeuralModel::CreateFromFile(modelPath);
@@ -134,29 +141,36 @@ void RunNAMTests(std::filesystem::path modelPath, int blockSize)
134141

135142
double rms;
136143

137-
if (namCoreModel != nullptr)
138-
{
139-
}
140-
141144
std::tuple<double, double> internal;
142145
std::tuple<double, double> rtNeural;
143146
std::tuple<double, double> namCore;
144147

145-
internal = BenchModel(internalModel, blockSize, numBlocks);
148+
if (internalModel != nullptr)
149+
{
150+
internal = BenchModel(internalModel, blockSize, numBlocks);
146151

147-
std::cout << "Internal: " << std::get<0>(internal) << " (" << std::get<1>(internal) << ")" << std::endl;
152+
std::cout << "Internal: " << std::get<0>(internal) << " (" << std::get<1>(internal) << ")" << std::endl;
153+
}
154+
else
155+
{
156+
std::cout << "Model can't be loaded as internal model" << std::endl;
157+
}
148158

149159
if (namCoreModel != nullptr)
150160
{
151161
std::cout << std::endl;
152162

153163
namCore = BenchModel(namCoreModel, blockSize, numBlocks);
154164

155-
rms = ComputeError(namCoreModel, internalModel, blockSize, numBlocks);
156-
157165
std::cout << "NAM Core: " << std::get<0>(namCore) << " (" << std::get<1>(namCore) << ")" << std::endl;
158-
std::cout << "NAM vs Internal RMS err: " << rms << std::endl;
159-
std::cout << "Internal is: " << (std::get<0>(namCore) / std::get<0>(internal)) << "x NAM" << std::endl;
166+
167+
if (internalModel != nullptr)
168+
{
169+
rms = ComputeError(namCoreModel, internalModel, blockSize, numBlocks);
170+
171+
std::cout << "NAM vs Internal RMS err: " << rms << std::endl;
172+
std::cout << "Internal is: " << (std::get<0>(namCore) / std::get<0>(internal)) << "x NAM" << std::endl;
173+
}
160174
}
161175

162176
if (rtNeuralModel != nullptr)
@@ -166,12 +180,16 @@ void RunNAMTests(std::filesystem::path modelPath, int blockSize)
166180
rtNeural = BenchModel(rtNeuralModel, blockSize, numBlocks);
167181

168182
std::cout << "RTNeural: " << std::get<0>(rtNeural) << " (" << std::get<1>(rtNeural) << ")" << std::endl;
169-
rms = ComputeError(namCoreModel, rtNeuralModel, blockSize, numBlocks);
170-
std::cout << "NAM vs RTNeural RMS err: " << rms << std::endl;
171183

172184
if (namCoreModel != nullptr)
173185
{
174-
std::cout << "RTNeural is: " << (std::get<0>(namCore) / std::get<0>(rtNeural)) << "x NAM" << std::endl;
186+
rms = ComputeError(namCoreModel, rtNeuralModel, blockSize, numBlocks);
187+
std::cout << "NAM vs RTNeural RMS err: " << rms << std::endl;
188+
189+
if (namCoreModel != nullptr)
190+
{
191+
std::cout << "RTNeural is: " << (std::get<0>(namCore) / std::get<0>(rtNeural)) << "x NAM" << std::endl;
192+
}
175193
}
176194
}
177195

0 commit comments

Comments
 (0)