Qwen
/

有没有人写一个stream_chat,现在的体验有点差

#6
by Weiguo - opened

这个应该是基本需求吧

Try xinference(https://github.com/xorbitsai/inference), it has supported qwen and generate in stream.

diff --git a/modeling_qwen.py b/modeling_qwen.py
index cc58746..a0361d9 100644
--- a/modeling_qwen.py
+++ b/modeling_qwen.py
@@ -883,6 +883,7 @@ class QWenLMHeadModel(QWenPreTrainedModel):
         history: Optional[HistoryType],
         system: str = "You are a helpful assistant.",
         append_history: bool = True,
+        stream: Optional[bool] = False,
     ) -> Tuple[str, HistoryType]:
 
         if history is None:
@@ -902,25 +903,39 @@ class QWenLMHeadModel(QWenPreTrainedModel):
         )
         input_ids = torch.tensor([context_tokens]).to(self.device)
 
-        outputs = self.generate(
-            input_ids,
-            stop_words_ids=stop_words_ids,
-            return_dict_in_generate=False,
-        )
+        if stream:
+            from transformers_stream_generator.main import NewGenerationMixin, StreamGenerationConfig
+            self.__class__.generate = NewGenerationMixin.generate
+            self.__class__.sample_stream = NewGenerationMixin.sample_stream
+            stream_config = StreamGenerationConfig(**self.generation_config.to_dict(), do_stream=True)
 
-        response = decode_tokens(
-            outputs[0],
-            tokenizer,
-            raw_text_len=len(raw_text),
-            context_length=len(context_tokens),
-            chat_format=self.generation_config.chat_format,
-            verbose=False,
-        )
+            def stream_generator():
+                outputs = []
+                for token in self.generate(input_ids, stop_words_ids=stop_words_ids, return_dict_in_generate=False, generation_config=stream_config):
+                    outputs.append(token.item())
+                    yield tokenizer.decode(outputs, skip_special_tokens=True)
+
+            return stream_generator()
+        else:
+            outputs = self.generate(
+                input_ids,
+                stop_words_ids=stop_words_ids,
+                return_dict_in_generate=False,
+            )
+
+            response = decode_tokens(
+                outputs[0],
+                tokenizer,
+                raw_text_len=len(raw_text),
+                context_length=len(context_tokens),
+                chat_format=self.generation_config.chat_format,
+                verbose=False,
+            )
 
-        if append_history:
-            history.append((query, response))
+            if append_history:
+                history.append((query, response))
 
-        return response, history
+            return response, history
 
     def generate(
         self,

好像没有合并进去

好像没有合并进去

不知道官方会怎么改,不一定合这个版本的。自己临时性用的话,可以改modeling_qwen.py.

另外,这里好像有个bug,
这个if有时候可能会导致self._rotary_pos_emb_cacheNone.
我直接暴力的把if 去掉,好像也能跑 😊

好像没有合并进去

不知道官方会怎么改,不一定合这个版本的。自己临时性用的话,可以改modeling_qwen.py.

另外,这里好像有个bug,
这个if有时候可能会导致self._rotary_pos_emb_cacheNone.
我直接暴力的把if 去掉,好像也能跑 😊

这个stream chat会出现一些奇怪的输出

截图 2023-08-04 17-11-11.png

我把输出长度调整了一下

model.generation_config.max_context_size=2048
model.generation_config.max_generate_size=1024
model.generation_config.max_new_tokens=1024

等官方吧

已经更新了streaming输出,示例在cli_demo.py

@JustinLin610 streaming接口是不是有点小问题,第一次chat的时候,如果第一条message是Hi,有很大概率会报错。
这里的update_rotary_pos_emb_cache有时候可能会导致self._rotary_pos_emb_cache为None?

image.png

这个应该是基本需求吧

我找到了这个工程是可以直接跑stream的
https://github.com/xusenlinzy/api-for-open-llm/blob/master/docs/SCRIPT.md#qwen-7b-chat

@JustinLin610 streaming接口是不是有点小问题,第一次chat的时候,如果第一条message是Hi,有很大概率会报错。
这里的update_rotary_pos_emb_cache有时候可能会导致self._rotary_pos_emb_cache为None?

image.png

目前已经更新了写法,现在用的是新的分开写的chat_stream的

JustinLin610 changed discussion status to closed

Sign up or log in to comment