Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions egs/sre08/v1/sid/nnet3/xvector/extract_xvectors.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@
# Begin configuration section.
nj=30
cmd="run.pl"
chunk_size=-1 # The chunk size over which the embedding is extracted.
# If left unspecified, it uses the max_chunk_size in the nnet
# directory.

cache_capacity=64 # Cache capacity for x-vector extractor
chunk_size=-1 # The chunk size over which the embedding is extracted.
# If left unspecified, it uses the max_chunk_size in the nnet
# directory.
use_gpu=false
stage=0

Expand All @@ -34,6 +36,7 @@ if [ $# != 3 ]; then
echo " --use-gpu <bool|false> # If true, use GPU."
echo " --nj <n|30> # Number of jobs"
echo " --stage <stage|0> # To control partial reruns"
echo " --cache-capacity <n|64> # To speed-up xvector extraction"
echo " --chunk-size <n|-1> # If provided, extracts embeddings with specified"
echo " # chunk size, and averages to produce final embedding"
fi
Expand Down Expand Up @@ -77,13 +80,13 @@ if [ $stage -le 0 ]; then
if $use_gpu; then
for g in $(seq $nj); do
$cmd --gpu 1 ${dir}/log/extract.$g.log \
nnet3-xvector-compute --use-gpu=yes --min-chunk-size=$min_chunk_size --chunk-size=$chunk_size \
nnet3-xvector-compute --use-gpu=yes --min-chunk-size=$min_chunk_size --chunk-size=$chunk_size --cache-capacity=${cache_capacity} \
"$nnet" "`echo $feat | sed s/JOB/$g/g`" ark,scp:${dir}/xvector.$g.ark,${dir}/xvector.$g.scp || exit 1 &
done
wait
else
$cmd JOB=1:$nj ${dir}/log/extract.JOB.log \
nnet3-xvector-compute --use-gpu=no --min-chunk-size=$min_chunk_size --chunk-size=$chunk_size \
nnet3-xvector-compute --use-gpu=no --min-chunk-size=$min_chunk_size --chunk-size=$chunk_size --cache-capacity=${cache_capacity} \
"$nnet" "$feat" ark,scp:${dir}/xvector.JOB.ark,${dir}/xvector.JOB.scp || exit 1;
fi
fi
Expand Down
40 changes: 15 additions & 25 deletions src/chain/chain-supervision-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -157,35 +157,27 @@ void TestSupervisionAppend(const TransitionModel &trans_model,
std::vector<const Supervision*> input(num_append);
for (int32 i = 0; i < num_append; i++)
input[i] = &supervision;
std::vector<Supervision> output;
bool compactify = (RandInt(0, 1) == 0);
AppendSupervision(input, compactify, &output);
if (compactify) {
KALDI_ASSERT(output.size() == 1 &&
output[0].frames_per_sequence ==
supervision.frames_per_sequence &&
output[0].num_sequences == num_append);
} else {
KALDI_ASSERT(output.size() == input.size());
}
Supervision output;
AppendSupervision(input, &output);
KALDI_ASSERT(output.frames_per_sequence ==
supervision.frames_per_sequence &&
output.num_sequences == num_append);
int32 tot_sequences_in = 0, tot_sequences_out = 0,
tot_frames_in = 0, tot_frames_out = 0;
for (int32 i = 0; i < num_append; i++) {
tot_sequences_in += input[i]->num_sequences;
tot_frames_in += input[i]->num_sequences *
input[i]->frames_per_sequence;
}
for (int32 i = 0; i < output.size(); i++) {
tot_sequences_out += output[i].num_sequences;
tot_frames_out += output[i].num_sequences *
output[i].frames_per_sequence;
}
tot_sequences_out += output.num_sequences;
tot_frames_out += output.num_sequences *
output.frames_per_sequence;
KALDI_ASSERT(tot_sequences_out == tot_sequences_in &&
tot_frames_out == tot_frames_in);

TestSupervisionIo(output[0]);
TestSupervisionNumerator(output[0]);
output[0].Check(trans_model);
TestSupervisionIo(output);
TestSupervisionNumerator(output);
output.Check(trans_model);
}

void TestSupervisionReattached(const TransitionModel &trans_model,
Expand Down Expand Up @@ -368,18 +360,16 @@ void TestSupervisionSplitting(const ContextDependency &ctx_dep,
TestSupervisionIo(split_supervision[RandInt(0, num_ranges - 1)]);
TestSupervisionFrames(split_supervision[RandInt(0, num_ranges - 1)]);

std::vector<Supervision> reattached_supervision;
Supervision reattached_supervision;
std::vector<const Supervision*> to_append(num_ranges);
for (int32 i = 0; i < num_ranges; i++)
to_append[i] = &(split_supervision[i]);
bool compactify = true;
AppendSupervision(to_append, compactify, &reattached_supervision);
KALDI_ASSERT(reattached_supervision.size() == 1);
ChainTrainingTest(den_graph, reattached_supervision[0]);
AppendSupervision(to_append, &reattached_supervision);
ChainTrainingTest(den_graph, reattached_supervision);
if (num_frames % frames_per_range == 0) {
TestSupervisionReattached(trans_model,
supervision,
reattached_supervision[0]);
reattached_supervision);
}
}
}
Expand Down
56 changes: 21 additions & 35 deletions src/chain/chain-supervision.cc
Original file line number Diff line number Diff line change
Expand Up @@ -694,71 +694,57 @@ Supervision::Supervision(const Supervision &other):
// This static function is called by AppendSupervision if the supervisions
// are end2end. It simply puts all e2e FST's into 1 supervision.
void AppendSupervisionE2e(const std::vector<const Supervision*> &input,
bool compactify,
std::vector<Supervision> *output_supervision) {
Supervision *output_supervision) {
KALDI_ASSERT(!input.empty());
KALDI_ASSERT(input[0]->e2e);
output_supervision->clear();
output_supervision->resize(1);
KALDI_ASSERT(input[0]->e2e_fsts.size() == 1);
(*output_supervision)[0] = *(input[0]);
*output_supervision = *(input[0]);
for (int32 i = 1; i < input.size(); i++) {
(*output_supervision)[0].num_sequences++;
output_supervision->num_sequences++;
KALDI_ASSERT(input[i]->e2e_fsts.size() == 1);
KALDI_ASSERT(input[i]->frames_per_sequence ==
(*output_supervision)[0].frames_per_sequence);
(*output_supervision)[0].e2e_fsts.push_back(input[i]->e2e_fsts[0]);
output_supervision->frames_per_sequence);
output_supervision->e2e_fsts.push_back(input[i]->e2e_fsts[0]);
}
}

void AppendSupervision(const std::vector<const Supervision*> &input,
bool compactify,
std::vector<Supervision> *output_supervision) {
Supervision *output_supervision) {
KALDI_ASSERT(!input.empty());
int32 label_dim = input[0]->label_dim,
num_inputs = input.size();
if (num_inputs == 1) {
output_supervision->resize(1);
(*output_supervision)[0] = *(input[0]);
*output_supervision = *(input[0]);
return;
}
if (input[0]->e2e) {
AppendSupervisionE2e(input, compactify, output_supervision);
AppendSupervisionE2e(input, output_supervision);
return;
}

std::vector<bool> output_was_merged;
for (int32 i = 1; i < num_inputs; i++)
KALDI_ASSERT(input[i]->label_dim == label_dim &&
"Trying to append incompatible Supervision objects");
output_supervision->clear();
output_supervision->reserve(input.size());
for (int32 i = 0; i < input.size(); i++) {
*output_supervision = *(input[num_inputs-1]);
for (int32 i = num_inputs - 2; i >= 0; i--) {
const Supervision &src = *(input[i]);
if (compactify && !output_supervision->empty() &&
output_supervision->back().weight == src.weight &&
output_supervision->back().frames_per_sequence ==
if (output_supervision->weight == src.weight &&
output_supervision->frames_per_sequence ==
src.frames_per_sequence) {
// Combine with current output
// append src.fst to output_supervision->fst.
fst::Concat(&output_supervision->back().fst, src.fst);
output_supervision->back().num_sequences++;
output_was_merged.back() = true;
// the complexity here is O(V1 + E1)
fst::Concat(src.fst, &output_supervision->fst);
output_supervision->num_sequences++;
} else {
output_supervision->resize(output_supervision->size() + 1);
output_supervision->back() = src;
output_was_merged.push_back(false);
}
}
KALDI_ASSERT(output_was_merged.size() == output_supervision->size());
for (size_t i = 0; i < output_supervision->size(); i++) {
if (output_was_merged[i]) {
fst::StdVectorFst &out_fst = (*output_supervision)[i].fst;
// The process of concatenation will have introduced epsilons.
fst::RmEpsilon(&out_fst);
SortBreadthFirstSearch(&out_fst);
KALDI_ERR << "Mismatch weight or frames_per_sequence between inputs";
}

}
fst::StdVectorFst &out_fst = output_supervision->fst;
// The process of concatenation will have introduced epsilons.
fst::RmEpsilon(&out_fst);
SortBreadthFirstSearch(&out_fst);
}

// This static function is called by AddWeightToSupervisionFst if the supervision
Expand Down
7 changes: 3 additions & 4 deletions src/chain/chain-supervision.h
Original file line number Diff line number Diff line change
Expand Up @@ -380,15 +380,14 @@ int32 ComputeFstStateTimes(const fst::StdVectorFst &fst,
/// This function appends a list of supervision objects to create what will
/// usually be a single such object, but if the weights and num-frames are not
/// all the same it will only append Supervision objects where successive ones
/// have the same weight and num-frames, and if 'compactify' is true. The
/// normal use-case for this is when you are combining neural-net examples for
/// have the same weight and num-frames.
/// The normal use-case for this is when you are combining neural-net examples for
/// training; appending them like this helps to simplify the training process.

/// This function will crash if the values of label_dim in the inputs are not
/// all the same.
void AppendSupervision(const std::vector<const Supervision*> &input,
bool compactify,
std::vector<Supervision> *output_supervision);
Supervision *output_supervision);


/// This function helps you to pseudo-randomly split a sequence of length 'num_frames',
Expand Down
41 changes: 14 additions & 27 deletions src/nnet3/discriminative-supervision.cc
Original file line number Diff line number Diff line change
Expand Up @@ -400,49 +400,36 @@ void DiscriminativeSupervisionSplitter::ComputeLatticeScores(const Lattice &lat,
}

void AppendSupervision(const std::vector<const DiscriminativeSupervision*> &input,
bool compactify,
std::vector<DiscriminativeSupervision> *output_supervision) {
DiscriminativeSupervision *output_supervision) {
KALDI_ASSERT(!input.empty());
int32 num_inputs = input.size();
if (num_inputs == 1) {
output_supervision->resize(1);
(*output_supervision)[0] = *(input[0]);
*output_supervision = *(input[0]);
return;
}
std::vector<bool> output_was_merged;
output_supervision->clear();
output_supervision->reserve(input.size());
for (int32 i = 0; i < input.size(); i++) {
*output_supervision = *(input[num_inputs-1]);
for (int32 i = num_inputs - 2; i >= 0; i--) {
const DiscriminativeSupervision &src = *(input[i]);
KALDI_ASSERT(src.num_sequences == 1);
if (compactify && !output_supervision->empty() &&
output_supervision->back().weight == src.weight &&
output_supervision->back().frames_per_sequence ==
if (output_supervision->weight == src.weight &&
output_supervision->frames_per_sequence ==
src.frames_per_sequence) {
// Combine with current output
// append src.den_lat to output_supervision->den_lat.
fst::Concat(&output_supervision->back().den_lat, src.den_lat);
fst::Concat(src.den_lat, &output_supervision->den_lat);

output_supervision->back().num_ali.insert(
output_supervision->back().num_ali.end(),
output_supervision->num_ali.insert(
output_supervision->num_ali.begin(),
src.num_ali.begin(), src.num_ali.end());

output_supervision->back().num_sequences++;
output_was_merged.back() = true;
output_supervision->num_sequences++;
} else {
output_supervision->resize(output_supervision->size() + 1);
output_supervision->back() = src;
output_was_merged.push_back(false);
}
}
KALDI_ASSERT(output_was_merged.size() == output_supervision->size());
for (size_t i = 0; i < output_supervision->size(); i++) {
if (output_was_merged[i]) {
DiscriminativeSupervision &out_sup = (*output_supervision)[i];
fst::TopSort(&(out_sup.den_lat));
out_sup.Check();
KALDI_ERR << "Mismatch weight or frames_per_sequence between inputs";
}
}
DiscriminativeSupervision &out_sup = *output_supervision;
fst::TopSort(&(out_sup.den_lat));
out_sup.Check();
}

} // namespace discriminative
Expand Down
3 changes: 1 addition & 2 deletions src/nnet3/discriminative-supervision.h
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,7 @@ class DiscriminativeSupervisionSplitter {
/// training; appending them like this helps to simplify the training process.

void AppendSupervision(const std::vector<const DiscriminativeSupervision*> &input,
bool compactify,
std::vector<DiscriminativeSupervision> *output_supervision);
DiscriminativeSupervision *output_supervision);


} // namespace discriminative
Expand Down
1 change: 0 additions & 1 deletion src/nnet3/natural-gradient-online.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
#define KALDI_NNET3_NATURAL_GRADIENT_ONLINE_H_

#include <iostream>
#include <mutex>
#include "base/kaldi-common.h"
#include "matrix/matrix-lib.h"
#include "cudamatrix/cu-matrix-lib.h"
Expand Down
2 changes: 1 addition & 1 deletion src/nnet3/nnet-am-decodable-simple.cc
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ void DecodableNnetSimple::DoNnetComputation(
request.outputs.resize(1);
request.outputs[0].Swap(&output_spec);

const NnetComputation *computation = compiler_.Compile(request);
std::shared_ptr<const NnetComputation> computation = compiler_.Compile(request);
Nnet *nnet_to_update = NULL; // we're not doing any update.
NnetComputer computer(opts_.compute_config, *computation,
nnet_, nnet_to_update);
Expand Down
2 changes: 1 addition & 1 deletion src/nnet3/nnet-chain-diagnostics.cc
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ void NnetChainComputeProb::Compute(const NnetChainExample &chain_eg) {
GetChainComputationRequest(nnet_, chain_eg, need_model_derivative,
store_component_stats, use_xent_regularization,
use_xent_derivative, &request);
const NnetComputation *computation = compiler_.Compile(request);
std::shared_ptr<const NnetComputation> computation = compiler_.Compile(request);
NnetComputer computer(nnet_config_.compute_config, *computation,
nnet_, deriv_nnet_);
// give the inputs to the computer object.
Expand Down
9 changes: 2 additions & 7 deletions src/nnet3/nnet-chain-example.cc
Original file line number Diff line number Diff line change
Expand Up @@ -204,15 +204,10 @@ static void MergeSupervision(
input_supervision.reserve(inputs.size());
for (int32 n = 0; n < num_inputs; n++)
input_supervision.push_back(&(inputs[n]->supervision));
std::vector<chain::Supervision> output_supervision;
bool compactify = true;
chain::Supervision output_supervision;
AppendSupervision(input_supervision,
compactify,
&output_supervision);
if (output_supervision.size() != 1)
KALDI_ERR << "Failed to merge 'chain' examples-- inconsistent lengths "
<< "or weights?";
output->supervision.Swap(&(output_supervision[0]));
output->supervision.Swap(&output_supervision);

output->indexes.clear();
output->indexes.reserve(num_indexes);
Expand Down
2 changes: 1 addition & 1 deletion src/nnet3/nnet-chain-training.cc
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ void NnetChainTrainer::Train(const NnetChainExample &chain_eg) {
nnet_config.store_component_stats,
use_xent_regularization, need_model_derivative,
&request);
const NnetComputation *computation = compiler_.Compile(request);
std::shared_ptr<const NnetComputation> computation = compiler_.Compile(request);

if (nnet_config.backstitch_training_scale > 0.0 && num_minibatches_processed_
% nnet_config.backstitch_training_interval ==
Expand Down
1 change: 0 additions & 1 deletion src/nnet3/nnet-component-itf.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
#define KALDI_NNET3_NNET_COMPONENT_ITF_H_

#include <iostream>
#include <mutex>
#include "nnet3/nnet-common.h"
#include "nnet3/nnet-parse.h"
#include "base/kaldi-error.h"
Expand Down
17 changes: 17 additions & 0 deletions src/nnet3/nnet-computation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1199,6 +1199,23 @@ size_t IoSpecificationHasher::operator () (
(io_spec.has_deriv ? 4261 : 0);
}

// ComputationRequests are distinguished by the names and indexes
// of inputs and outputs
size_t ComputationRequestHasher::operator() (
const ComputationRequest *cr) const noexcept {
size_t ans = 0;
size_t p1 = 4111, p2 = 26951;
IoSpecificationHasher io_hasher;
std::vector<IoSpecification>::const_iterator itr = cr->inputs.begin(),
end = cr->inputs.end();
for (; itr != end; ++itr)
ans = ans * p1 + io_hasher(*itr);
itr = cr->outputs.begin();
end = cr->outputs.end();
for (; itr != end; ++itr)
ans = ans * p2 + io_hasher(*itr);
return ans;
}



Expand Down
Loading