Beispiel #1
0
    def test_case1(self):
        # refer to https://github.com/baidu-research/warp-ctc/blob/master/torch_binding/TUTORIAL.md

        # this is the simplest case
        # we have one sequence with probability: [0.2, 0.2, 0.2, 0.2, 0.2]
        label_lengths_tensor = torch.tensor([1], dtype=torch.int32)
        input_lengths_tensor = torch.tensor([1], dtype=torch.int32)
        alphabet_size = 5
        minibatch = 1
        info = ctc.CtcOptions()
        info.loc = ctc.CtcComputeLocation.CTC_CPU
        info.num_threads = 0  # use default number of threads
        info.blank_label = 0

        label_lengths = kaldi.IntSubVectorFromDLPack(
            to_dlpack(label_lengths_tensor))

        input_lengths = kaldi.IntSubVectorFromDLPack(
            to_dlpack(input_lengths_tensor))

        status, size_in_bytes = ctc.GetWorkspaceSize(
            label_lengths=label_lengths,
            input_lengths=input_lengths,
            alphabet_size=alphabet_size,
            minibatch=minibatch,
            info=info)
        self.assertEqual(status, ctc.CtcStatus.CTC_STATUS_SUCCESS)
        num_floats = size_in_bytes // 4 + 1
        workspace_tensor = torch.empty(num_floats,
                                       dtype=torch.float32).contiguous()

        activations_tensor = torch.tensor([0.2, 0.2, 0.2, 0.2, 0.2],
                                          dtype=torch.float32).contiguous()
        gradients_tensor = torch.empty_like(activations_tensor)
        flat_labels_tensor = torch.tensor([1], dtype=torch.int32)
        costs_tensor = torch.empty(minibatch, dtype=torch.float32)

        activations = kaldi.FloatSubVectorFromDLPack(
            to_dlpack(activations_tensor))
        gradients = kaldi.FloatSubVectorFromDLPack(to_dlpack(gradients_tensor))
        flat_labels = kaldi.IntSubVectorFromDLPack(
            to_dlpack(flat_labels_tensor))
        costs = kaldi.FloatSubVectorFromDLPack(to_dlpack(costs_tensor))
        workspace = kaldi.FloatSubVectorFromDLPack(to_dlpack(workspace_tensor))

        status = ctc.ComputeCtcLossCpu(activations=activations,
                                       gradients=gradients,
                                       flat_labels=flat_labels,
                                       label_lengths=label_lengths,
                                       input_lengths=input_lengths,
                                       alphabet_size=alphabet_size,
                                       minibatch=minibatch,
                                       costs=costs,
                                       workspace=workspace,
                                       options=info)

        # 1.6094379425049 is copied from
        # https://github.com/baidu-research/warp-ctc/blob/master/torch_binding/TUTORIAL.md
        self.assertAlmostEqual(costs[0], 1.6094379425049)
Beispiel #2
0
    def test_dlpack_subvector(self):
        '''
        kaldi.Hello accepts two parameters:
            Param 1: reference to VectorBase<float>
            Param 2: pointer to VectorBase<float>

        This test shows that we can pass a DLPackSubVector
        to `Hello`.
        '''
        tensor1 = torch.tensor([1, 2]).float()
        v1 = kaldi.FloatSubVectorFromDLPack(to_dlpack(tensor1))

        tensor2 = torch.tensor([10, 20, 30]).float()
        v2 = kaldi.FloatSubVectorFromDLPack(to_dlpack(tensor2))

        kaldi.Hello(v1, v2)
Beispiel #3
0
    def test_pytorch_cpu_tensor_to_subvector(self):
        '''
        Note that we have two ways to convert a
        PyTorch CPU tensor to kaldi's FloatSubVector:

        Method 1:
            v = kaldi.FloatSubVectorFromDLPack(to_dlpack(tensor))

        Method 2:
            v = kaldi.DLPackFloatSubVector.from_dlpack(to_dlpack(tensor))
        '''
        tensor = torch.arange(3).float()

        # v and tensor share the same memory
        # no data is copied
        v = kaldi.FloatSubVectorFromDLPack(to_dlpack(tensor))
        # since DLPackFloatSubVector is a subclass of FloatSubVector
        # the following assertion is True
        self.assertIsInstance(v, kaldi.FloatSubVector)

        v[0] = 100
        v[1] = 200
        v[2] = 300

        self.assertEqual(tensor[0], 100)
        self.assertEqual(tensor[1], 200)
        self.assertEqual(tensor[2], 300)

        del v
        # the destructor of DLPackFloatSubVector is invoked
        # by the above `del v` statement, you should see the log message
        # here if you have put it in the destructor.

        # memory is shared between `v` and `tensor`
        v = kaldi.DLPackFloatSubVector.from_dlpack(to_dlpack(tensor))
        self.assertEqual(v[0], 100)

        v[0] = 1  # also changes tensor
        self.assertEqual(tensor[0], 1)
Beispiel #4
0
    def test_case4(self):
        # combine case1 to case3 to a minibatch
        # the first example (a): input_length: 1, label_length: 1
        # the second example (c, c): input_length: 3, label_length: 2
        # the third example (b, c): input_length: 3, label_length: 2
        label_lengths_tensor = torch.tensor([1, 2, 2], dtype=torch.int32)
        input_lengths_tensor = torch.tensor([1, 3, 3], dtype=torch.int32)

        alphabet_size = 5
        minibatch = 3
        info = ctc.CtcOptions()
        info.loc = ctc.CtcComputeLocation.CTC_CPU
        info.num_threads = 0  # use default number of threads
        info.blank_label = 0

        label_lengths = kaldi.IntSubVectorFromDLPack(
            to_dlpack(label_lengths_tensor))

        input_lengths = kaldi.IntSubVectorFromDLPack(
            to_dlpack(input_lengths_tensor))

        status, size_in_bytes = ctc.GetWorkspaceSize(
            label_lengths=label_lengths,
            input_lengths=input_lengths,
            alphabet_size=alphabet_size,
            minibatch=minibatch,
            info=info)
        self.assertEqual(status, ctc.CtcStatus.CTC_STATUS_SUCCESS)
        num_floats = size_in_bytes // 4 + 1
        workspace_tensor = torch.empty(num_floats,
                                       dtype=torch.float32).contiguous()

        ex1 = torch.tensor([[0.2, 0.2, 0.2, 0.2, 0.2]], dtype=torch.float32)

        ex2 = torch.tensor(
            [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]],
            dtype=torch.float32)

        ex3 = torch.tensor([[-5, -4, -3, -2, -1], [-10, -9, -8, -7, -6],
                            [-15, -14, -13, -12, -11]],
                           dtype=torch.float32)

        activations_tensor = pad_sequence([ex1, ex2, ex3], batch_first=False)

        activations_tensor = activations_tensor.contiguous().view(-1)
        gradients_tensor = torch.empty_like(activations_tensor)

        # labels are: (a), (c, c) (b, c)
        # which are:  (1), (3, 3), (2, 3)
        flat_labels_tensor = torch.tensor([1, 3, 3, 2, 3], dtype=torch.int32)
        costs_tensor = torch.empty(minibatch, dtype=torch.float32)

        activations = kaldi.FloatSubVectorFromDLPack(
            to_dlpack(activations_tensor))
        gradients = kaldi.FloatSubVectorFromDLPack(to_dlpack(gradients_tensor))
        flat_labels = kaldi.IntSubVectorFromDLPack(
            to_dlpack(flat_labels_tensor))
        costs = kaldi.FloatSubVectorFromDLPack(to_dlpack(costs_tensor))
        workspace = kaldi.FloatSubVectorFromDLPack(to_dlpack(workspace_tensor))

        status = ctc.ComputeCtcLossCpu(activations=activations,
                                       gradients=gradients,
                                       flat_labels=flat_labels,
                                       label_lengths=label_lengths,
                                       input_lengths=input_lengths,
                                       alphabet_size=alphabet_size,
                                       minibatch=minibatch,
                                       costs=costs,
                                       workspace=workspace,
                                       options=info)

        self.assertAlmostEqual(costs[0], 1.6094379425049)
        self.assertAlmostEqual(costs[1], 7.355742931366)
        self.assertAlmostEqual(costs[2], 4.938850402832, places=6)
Beispiel #5
0
    def test_case3(self):
        # this is the third case
        # we have 3 sequences with probability:
        # [-5, -4, -3, -2, -1]
        # [-10, -9, -8, -7, -6]
        # [-15, -14, -13, -12, -11]
        label_lengths_tensor = torch.tensor([2], dtype=torch.int32)
        input_lengths_tensor = torch.tensor([3], dtype=torch.int32)
        alphabet_size = 5
        minibatch = 1
        info = ctc.CtcOptions()
        info.loc = ctc.CtcComputeLocation.CTC_CPU
        info.num_threads = 0  # use default number of threads
        info.blank_label = 0

        label_lengths = kaldi.IntSubVectorFromDLPack(
            to_dlpack(label_lengths_tensor))

        input_lengths = kaldi.IntSubVectorFromDLPack(
            to_dlpack(input_lengths_tensor))

        status, size_in_bytes = ctc.GetWorkspaceSize(
            label_lengths=label_lengths,
            input_lengths=input_lengths,
            alphabet_size=alphabet_size,
            minibatch=minibatch,
            info=info)
        self.assertEqual(status, ctc.CtcStatus.CTC_STATUS_SUCCESS)
        num_floats = size_in_bytes // 4 + 1
        workspace_tensor = torch.empty(num_floats,
                                       dtype=torch.float32).contiguous()

        activations_tensor = torch.tensor(
            [[-5, -4, -3, -2, -1], [-10, -9, -8, -7, -6],
             [-15, -14, -13, -12, -11]],
            dtype=torch.float32).contiguous().view(-1)
        gradients_tensor = torch.empty_like(activations_tensor)
        # the target sequence is b c, whichis 2 3
        flat_labels_tensor = torch.tensor([2, 3], dtype=torch.int32)
        costs_tensor = torch.empty(minibatch, dtype=torch.float32)

        activations = kaldi.FloatSubVectorFromDLPack(
            to_dlpack(activations_tensor))
        gradients = kaldi.FloatSubVectorFromDLPack(to_dlpack(gradients_tensor))
        flat_labels = kaldi.IntSubVectorFromDLPack(
            to_dlpack(flat_labels_tensor))
        costs = kaldi.FloatSubVectorFromDLPack(to_dlpack(costs_tensor))
        workspace = kaldi.FloatSubVectorFromDLPack(to_dlpack(workspace_tensor))

        status = ctc.ComputeCtcLossCpu(activations=activations,
                                       gradients=gradients,
                                       flat_labels=flat_labels,
                                       label_lengths=label_lengths,
                                       input_lengths=input_lengths,
                                       alphabet_size=alphabet_size,
                                       minibatch=minibatch,
                                       costs=costs,
                                       workspace=workspace,
                                       options=info)

        # 4.938850402832 is copied from
        # https://github.com/baidu-research/warp-ctc/blob/master/torch_binding/TUTORIAL.md
        self.assertAlmostEqual(costs[0], 4.938850402832, places=6)
Beispiel #6
0
    def test_case2(self):
        device = torch.device('cuda', device_id)
        # this is the second case
        # we have 3 sequences with probability:
        # [1, 2, 3, 4, 5]
        # [6, 7, 8, 9, 10]
        # [11, 12, 13, 14, 15]
        label_lengths_tensor = torch.tensor([2], dtype=torch.int32)
        input_lengths_tensor = torch.tensor([3], dtype=torch.int32)
        alphabet_size = 5
        minibatch = 1
        info = ctc.CtcOptions()
        info.loc = ctc.CtcComputeLocation.CTC_GPU
        info.blank_label = 0

        label_lengths = kaldi.IntSubVectorFromDLPack(
            to_dlpack(label_lengths_tensor))

        input_lengths = kaldi.IntSubVectorFromDLPack(
            to_dlpack(input_lengths_tensor))

        status, size_in_bytes = ctc.GetWorkspaceSize(
            label_lengths=label_lengths,
            input_lengths=input_lengths,
            alphabet_size=alphabet_size,
            minibatch=minibatch,
            info=info)
        self.assertEqual(status, ctc.CtcStatus.CTC_STATUS_SUCCESS)
        num_floats = size_in_bytes // 4 + 1
        workspace_tensor = torch.empty(
            num_floats, dtype=torch.float32).contiguous().to(device)

        activations_tensor = torch.tensor(
            [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]],
            dtype=torch.float32).contiguous().view(-1).to(device)
        gradients_tensor = torch.empty_like(activations_tensor)

        # the target sequence is cc, which is 3 3
        flat_labels_tensor = torch.tensor([3, 3], dtype=torch.int32)
        costs_tensor = torch.empty(minibatch, dtype=torch.float32)

        activations = kaldi.CuSubVectorFromDLPack(to_dlpack(activations_tensor))
        gradients = kaldi.CuSubVectorFromDLPack(to_dlpack(gradients_tensor))
        flat_labels = kaldi.IntSubVectorFromDLPack(
            to_dlpack(flat_labels_tensor))
        costs = kaldi.FloatSubVectorFromDLPack(to_dlpack(costs_tensor))
        workspace = kaldi.CuSubVectorFromDLPack(to_dlpack(workspace_tensor))

        status = ctc.ComputeCtcLossGpu(activations=activations,
                                       gradients=gradients,
                                       flat_labels=flat_labels,
                                       label_lengths=label_lengths,
                                       input_lengths=input_lengths,
                                       alphabet_size=alphabet_size,
                                       minibatch=minibatch,
                                       costs=costs,
                                       workspace=workspace,
                                       options=info)

        # 7.355742931366 is copied from
        # https://github.com/baidu-research/warp-ctc/blob/master/torch_binding/TUTORIAL.md
        self.assertAlmostEqual(costs[0], 7.355742931366)