vocab = Vocabulary() vocab.load("data/vocabulary.json") print("Loading model...", flush=True) model = Seq2seqLSTM(vocab.size(), num_embed, num_hidden, num_layers) model.load_parameters("model/seq2seq_lstm.params", ctx=context) while True: try: source = input("> ") except EOFError: print("") break source = [vocab.char2idx(ch) for ch in source] source = pad_sentence( source, vocab, [2**(i + 1) for i in range(int(math.log(sequence_length, 2)))]) print(source) source = mx.nd.reverse(mx.nd.array(source, ctx=context), axis=0) hidden = model.begin_state(func=mx.nd.zeros, batch_size=1, ctx=context) hidden = model.encode(source.reshape((1, -1)).T, hidden) sequences = [([vocab.char2idx("<GO>")], 0.0, hidden)] while True: candidates = [] for seq, score, hidden in sequences: if seq[-1] == vocab.char2idx("<EOS>"): candidates.append((seq, score, hidden)) else: target = mx.nd.array([seq[-1]], ctx=context) output, hidden = model.decode( target.reshape((1, -1)).T, hidden)
def _handle_request(self): m = self._path_pattern.match(self.path) if not m or m.group(0) != self.path: self.send_response(http.HTTPStatus.BAD_REQUEST) self.end_headers() return if m.group(1) == "/coupletbot/say": params = {} if m.group(2): for param in urllib.parse.unquote(m.group(2)[1:]).split("&"): kv = self._param_pattern.match(param) if kv: params[kv.group(1)] = kv.group(2) content = params["content"] if not content: self.send_response(http.HTTPStatus.BAD_REQUEST) self.end_headers() return print(args.device_id, "say:", content) source = [vocab.char2idx(ch) for ch in content] source = pad_sentence( source, vocab, [2**(i + 1) for i in range(int(math.log(sequence_length, 2)))]) print(args.device_id, "tokenize:", source) source = mx.nd.reverse(mx.nd.array(source, ctx=context), axis=0) hidden = model.begin_state(func=mx.nd.zeros, batch_size=1, ctx=context) enc_out, hidden = model.encode(source.reshape((1, -1)).T, hidden) sequences = [([vocab.char2idx("<GO>")], 0.0, hidden)] while True: candidates = [] for seq, score, hidden in sequences: if seq[-1] == vocab.char2idx("<EOS>"): candidates.append((seq, score, hidden)) else: target = mx.nd.array([seq[-1]], ctx=context) output, hidden = model.decode( target.reshape((1, -1)).T, hidden, enc_out) probs = mx.nd.softmax(output, axis=1) beam = probs.reshape((-1, )).topk(k=beam_size, ret_typ="both") for i in range(beam_size): candidates.append( (seq + [int(beam[1][i].asscalar())], score + math.log(beam[0][i].asscalar()), hidden)) if len(candidates) <= len(sequences): break sequences = sorted(candidates, key=lambda tup: tup[1], reverse=True)[:beam_size] reply = "" for token in sequences[0][0][1:-1]: reply += vocab.idx2char(token) print(args.device_id, "reply:", reply) self.send_response(http.HTTPStatus.OK) self.send_header("Content-Type", "text/plain; charset=utf-8") self.send_header("Access-Control-Allow-Origin", "*") self.send_header("Access-Control-Allow-Methods", "GET,POST") self.send_header( "Access-Control-Allow-Headers", "Keep-Alive,User-Agent,Authorization,Content-Type") self.end_headers() self.wfile.write(reply.encode()) else: self.send_response(http.HTTPStatus.NOT_FOUND) self.end_headers() return