Hello,
Gear up to witness some very poorly written lines of code 
Here’s my model:
class CNN_NER(nn.Module): 
    def __init__(self,vocab_size,embedding_size):
        # vocab_size, embedding_size, window_size, hidden_size, output_size

        super(CNN_NER, self).__init__()
        
        self.embed = nn.Embedding(vocab_size, embedding_size)
        self.cnn1 = nn.Conv2d(in_channels=1,padding=2,out_channels=120,kernel_size=(11,54),stride=1,dilation=1)
        self.cnn2 = nn.Conv2d(in_channels=1,padding=2,out_channels=120,kernel_size=(10,54),stride=1,dilation=1)
        self.cnn3 = nn.Conv2d(in_channels=1,padding=2,out_channels=120,kernel_size=(9,54),stride=1,dilation=1)
#         self.cnn4 = nn.Conv2d(in_channels=100,padding=1,out_channels=100,kernel_size=(1,3),stride=1,dilation=1)
#         self.cnn5 = nn.Conv2d(in_channels=100,padding=1,out_channels=100,kernel_size=(1,4),stride=1,dilation=1)
#         self.cnn6 = nn.Conv2d(in_channels=100,padding=1,out_channels=100,kernel_size=(1,6),stride=1,dilation=1)
        
        self.relu = nn.ReLU()
        self.maxpool3 = nn.MaxPool2d(kernel_size=(1,3))
        self.maxpool4 = nn.MaxPool2d(kernel_size=(1,4))
        self.maxpool5 = nn.MaxPool2d(kernel_size=(1,5))
        self.linear = nn.Linear(40,9)
        self.softmax = nn.LogSoftmax()
        self.dropout = nn.Dropout(0.2)
        
    def forward(self,sent_grams,is_training):
        embeds = self.embed(sent_grams)
        embeds = embeds.unsqueeze(1)
        #print('inputs',embeds.size())
        
        l1 = self.cnn1(embeds)
        l1 = self.relu(l1)
        #print('cnn1',l1.size())
        l1 = l1.squeeze(3)
        l1 = self.maxpool3(l1)
        #print('maxpool3',l1.size())
        
        l2 = self.cnn2(embeds)
        l2 = self.relu(l2)
        #print('cnn2',l2.size())
        l2 = l2.squeeze(3)
        l2 = self.maxpool4(l2)
        #print('maxpool4',l2.size())
        
        l3 = self.cnn3(embeds)
        l3 = self.relu(l3)
        #print('cnn3',l3.size())
        l3 = l3.squeeze(3)
        l3 = self.maxpool5(l3)
        #print('maxpool5',l3.size())
        
        l4 = torch.cat((l1,l2,l3),1)
        #print('concatenated',l4.size())
        l4 = l4.view(l4.size(0),9,40)
        #print('quished before linear layer',l4.size())
        l5 = self.linear(l4)
        #print('output',l5.size())
        #l5 = self.softmax(l5)
        return l5

The loss and optimizers are:
'''define loss and optimizer'''
loss_function = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=LEARNING_RATE)

Training:
now = time.time()
for epoch in range(EPOCH):
    losses = []
    for i,batch in enumerate(getBatch(BATCH_SIZE, train_data)):
        
        x,y=list(zip(*batch))
        if len(x) == 128:
            inputs = torch.cat([prepare_sequence(sent, word2index).view(1, -1) for sent in x])
            targets = torch.cat([prepare_tag(tag, tag2index).view(1,-1) for tag in y])
            #print('input size',inputs.size())
            #print('target size',targets.size())
            model.zero_grad()
            preds = model(inputs, is_training=True)
            #print('preds,targets before loss',preds.size(),targets.size())
            loss = loss_function(preds, targets)
            losses.append(loss.data[0].cpu().numpy())
            loss.backward()
            optimizer.step()
            #print(loss)
            if i % 1000 == 0:
                total = 0.0
                correct = 0.0
                #Testing
                for i,batch in enumerate(getBatch(128, test_data)):
                    x,y=list(zip(*batch))
                    inputs = torch.cat([prepare_sequence(sent, word2index).view(1, -1) for sent in x])
                    targets = torch.cat([prepare_tag(tag, tag2index).view(1,-1) for tag in y])
                    model.zero_grad()
                    preds = model(inputs, is_training=False)
                    out = torch.max(preds,1)[1]
                    total += targets.size(0)*targets.size(1)
                    correct += (out.cpu()==targets.cpu()).sum()
                    acc = correct.double()/total * 100
                print("[%d/%d] mean_loss : %0.2f accuracy : %0.2f" %(epoch, EPOCH, np.mean(losses),acc))
                losses = []
print('time taken in seconds: {} seconds'.format(time.time()-now))

Edit:
prepare_sequence returns a sequence of word indices in my vocab against a sequence of words
eg:
prepare_sequence([‘EU’, ‘rejects’, ‘German’, ‘call’, ‘to’, ‘boycott’, ‘British’, ‘lamb’, ‘.’], word2index)
tensor([ 4029,  6314,  6213,  4033, 15398,  2473, 14625,  9766, 19587],
device=‘cuda:0’)
prepare_tag([‘O\n’, ‘O\n’, ‘B-ORG\n’, ‘O\n’, ‘B-MISC\n’],tag2index)
tensor([8, 8, 5, 8, 6], device=‘cuda:0’)
We concatenate 128 such sentences to embed and pass into our model along with the ‘tags’ or labels…for training. Each word changes into a 50 dimensional vector post embedding.
Same for testing.
Regards