GaiZhenbiao / ChuanhuChatGPT

GUI for ChatGPT API and many LLMs. Supports agents, file-based QA, GPT finetuning and query with web search. All with a neat UI.
https://huggingface.co/spaces/JohnSmith9982/ChuanhuChatGPT
GNU General Public License v3.0
15.14k stars 2.28k forks source link

A Fork request #122

Closed tuteng0915 closed 1 year ago

tuteng0915 commented 1 year ago

I have no development experience in the open source community before, so I don't dare to make trouble for you. I forked the project and made some changes to it in my repository:(haven push yet)

  1. Change the UI, the current top-bottom arrangement is very inconvenient to use, I moved many parts of the UI.
  2. The exception handling is a little naive. Although it is true that the error always comes from the token being too long, it still needs some processing.
  3. The function of summarizing the text didn't work for me, so I rewrote this part of the code to make it at least look better. I have no experience in collaborative development. My coding style sucks. And I think I've made enough changes. So, I'd prefer to edit in my own repo. And I would like to ask how to cite your work. Thx!
tuteng0915 commented 1 year ago
  1. The load of prompt template is a bit complicated, so I simplified the operation a bit.
  2. History and chatbot have some repetitions in the code, and I am sure (at least in a certain version) that it is precisely because of this repetition that the token summarizition fails, so I further differentiate their functions.
Keldos-Li commented 1 year ago

等川虎的意见ing……

等不及了,我作为协作者先稍写一些我的想法:

GaiZhenbiao commented 1 year ago

赞同Keldos说的~ 感谢你的工作!不过,我clone了你的代码,并没有发现有改动诶,是还没push到GitHub上吗?

tuteng0915 commented 1 year ago

好嘞 那稍等我一会儿

tuteng0915 commented 1 year ago

赞同Keldos说的~ 感谢你的工作!不过,我clone了你的代码,并没有发现有改动诶,是还没push到GitHub上吗?

因为我的代码风格很糟糕,所以还没有push ~

Keldos-Li commented 1 year ago

赞同Keldos说的~ 感谢你的工作!不过,我clone了你的代码,并没有发现有改动诶,是还没push到GitHub上吗?

因为我的代码风格很糟糕,所以还没有push ~

那或许你可以先在本地改改代码风格再push哈哈哈,不过等你提交pr之后我们应该也可以在分支里和你一起改orz

Keldos-Li commented 1 year ago

我添加了你的远程仓库到我的remote,发现到现在还没有任何变动,是有什么疑问或顾虑吗?我很乐意提供帮助~

GaiZhenbiao commented 1 year ago

我也感觉predict()函数写的太烂了……所以昨天重构了一下:)

tuteng0915 commented 1 year ago

因为近期代码进行了很大的重构工作,而我的开发基于4天前的版本,merge恐怕会有较多conflict,所以麻烦再给我一点点时间~

tuteng0915 commented 1 year ago

来检查作业吧~,我的api-key不知道为什么不好使了,所以今天就写到这了

Keldos-Li commented 1 year ago

来检查作业吧~,我的api-key不知道为什么不好使了,所以今天就写到这了

哎呀 因为你把apikey也commit了😂,被openai发现了。

我想想怎么做比较好……

……我看这也emrge来merge去的……不好直接pull……

我觉得可以这样,如果这些改动有必要,我们在这里开一个分支,然后我们把所需要的commit一个一个cherry-pick过来,cherry-pick的同时commit --amend把一些文档更改和不需要的东西改回去,(之后我们根据我们项目做一定修改,)最后rebase merge(是否需要squash再看?)进main。

这样,您将会是您所做commit的author,我们将会是co-author和commitor。

就是有点麻烦(

GaiZhenbiao commented 1 year ago

看了下,改动主要是👀

并且代码会在utils.py", line 163, in stream_predict报错json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0),而最新的主线代码是没有问题的。可能你还得排查下。

tuteng0915 commented 1 year ago
  1. 我并没能复现出这个报错,这个报错看起来是chunk解析问题?我没有改动这块的代码,不知是否是网络问题或没有填写api_key
  2. 事实上,这些改动并没有“真的改”,均可以通过命令行参数复原,也可以通过修改argparser的默认值来复原
  3. 本身预计修改的“History and chatbot have some repetitions”“The function of summarizing the text”在master分支中已经有了很好的实现,所以不再需要改动
  4. 接下去还会实现一个log功能,自动地记录每次对话的全过程以备部署者查看。(这主要是由于预期的应用场景不同,您们的项目旨在为所有拥有 api-key 的用户提供 WebUI 服务,我更倾向于提供给有api-key的人部署后分享给不拥有 api-key 的朋友使用)该功能也将可以由命令行参数来决定是否开启
  5. 关于如何merge,我的建议是这样的: i. 我修改argparse的默认值,使其在默认情况下不对master做任何变动 ii. 您们挑选一些确实有必要的功能, 我新开一个分支,仅保留这些功能 iii. 我在我的仓库里将这个分支与您们的仓库的最新分支进行merge vi. 在您的仓库里为我开一个分支,在检查之后再考虑是否merge到master中
tuteng0915 commented 1 year ago

关于token超出上限的情况这里给出另一套实现思路:

  1. 在predict函数中,首先统计history的长度,如果history超出某一个上限~3000,那么先行进行精简
  2. 非流式地生成精简结果后,从头扫描一遍history,直到token达到~2000,删除这部分history,并以固定地Prompt替换:

    user:[ChatGPT刚刚给出的结果](刚刚我们谈到了……),你了解了吗? assistant: 我了解了。 user: [原来的2000~3000聊天内容]

相比原来的实现,具有以下优势:

  1. 更加稳定,当前情况下,是在生成后再精简,如果用户本段token太长,除非用户先手动精简,否则将在触发一次“error”后被动地触发精简,用户体验差。
  2. 精简必将损失一些信息,用户对于最近的信息的精确性要求比聊天最开始的信息精确性要求更高
  3. 利于用户继续进行追问,否则上一条信息中的细节将因精简而消失,且由于该精简为被动触发,用户完全没有机会避免。

古早版本代码的修改建议如下:

        for index, data in enumerate(history):
            tmp = {}
            tmp["role"] = ["user", "assistant"][index % 2]
            tmp["content"] = data
            messages.append(tmp)
            message_token_cnt += len(data)
            if message_token_cnt > 2048 and index % 2 == 1:
                summary_at = index + 1
                break
        if summary_at != 0:
            messages.append(compose_user(
                "请帮我总结一下上述对话的内容,实现减少字数的同时,保证对话的质量。在总结中不要加入这一句话。"))
            response = openai.ChatCompletion.create(
                    model=MODEL,
                    messages=messages,
                    max_tokens=512
                )
            content = response["choices"][0]["message"]["content"] + "你了解了吗?"
            history = [content] + ["我了解了"] + history[summary_at:]

            messages = [compose_system(system_prompt)]
            for index, data in enumerate(history):
                tmp = {}
                tmp["role"] = ["user", "assistant"][index % 2]
                tmp["content"] = data
                messages.append(tmp)
Keldos-Li commented 1 year ago

(唉,我多么希望大家都能多分支并行开发,不同的feat放到不同的branch上,每一次commit就改一个东西,而不是一个commit里既改这个又改那个的……)

我把你的提交拆到了该仓库的两个分支上 (累死我了,一堆conflict)

如果你有更多修改,请在你的仓库另建至少两个对应的分支,然后

git reset --hard d759751
git pull upstream -f tt/ui (或tt/argparse)

之后在对应分支上修改对应的功能需求(尽量原子化提交commit),然后在这里向对应的分支提交pull request。


虽然我也不确定到底这些更改需不需要…… 建议是,一个需求一个需求解决,一个一个merge……

Keldos-Li commented 1 year ago

另外UI改动中,就这么把那些放到左边,在页面宽度较窄时它们会跑到上面:

image

这样对部署到服务器之后的窄屏输入并不友好…… (似乎最简单的方法是,把从放到左边改为放到右边)

tuteng0915 commented 1 year ago

不好意思,麻烦您了,我之前没有开源社区的开发经验,我会好好学的

是说应该每个feature单开一个branch,写好之后提交PR,在通过后,如果需要继续修改,就再拉取master,checkout -b,再提PR这样对吗?

另外,我没有特别理解这一部分:

如果你有更多修改,请在你的仓库另建至少两个对应的分支,然后
> git reset --hard d759751
> git pull upstream -f tt/ui (或tt/argparse)
之后在对应分支上修改对应的功能需求(尽量原子化提交commit),然后在这里向对应的分支提交pull request。

前半部分是我该在我的仓库里做的,请问为什么是要回到 d759751 这个commit,是因为 tt/ui 是从这个commit上分出去的吗?

后半部分“然后在这里向对应的分支提交pull request”是怎么做呢?我看PR里只能在一个仓库之内merge各个branch,可以大概告诉我一下该怎么做吗?另外,我现在完成了包括上述的log 和 精简token的修改,那么我是该:

  1. 在我的仓库里分别新建两个分支
  2. (您帮我?)在这个仓库里新建两个对应分支
  3. 从我的仓库提交PR到这个仓库的对应分支
  4. 再提交PR经过同意后再看是否merge到master中

是这样吗?

Keldos-Li commented 1 year ago

一般来说,一个功能一个branch看起来比较清楚,而且在请求pull之后仍可以持续提交。 至于已经合并之后继续改么……确实是再提新的PR。

第二个问题,为什么要回到d75,是因为你在这里执行过一次merge:

image

我怕git在本地更新的commit位置直接pull -f还是会产生自动合并,所以就先回到合并之前……另外我这里给了 pull -f 强制更新本地分支(因为我重新cherry-pick之后产生的是新的提交),所以务必确保本地没有commit,你的两个branch最好是全新的。

第三个问题,

image

最后的问题, 你应该:

  1. 在你的仓库里分别新建两个分支
  2. 从你的仓库直接提交PR到这个仓库的main,提交时选择你的仓库对应的分支。
Keldos-Li commented 1 year ago

另外,你”完成了包括上述的log 和 精简token的修改“的commit,最好是基于我们目前main的commit,确保父commit是 3b0ad6049c6500e8e8263200122894ea15c851e0 ,不要出现其他提交……否则,我们将无法merge(会把其他更改也merge进来)

如果你本地HEAD是在你自己的main 71dd362d566b3ffe0f4eab0bdb112162774ff698 的状态,我觉得你可以:

  1. 保存你的工作
  2. 先在branch1上提交(当然在你自己的main上也行吧)
  3. 新建并转到分支log
  4. 强制拉取我们的main覆盖本地git pull upstream -f main,确保该log分支和我们的main保持一致
  5. git cherry-pick [你刚才在branch1上提交的关于log修改的commit]
  6. 如有冲突,请解决
  7. 检查无误,在GitHub中提交pr
tuteng0915 commented 1 year ago

感谢耐心解答!最后这里我没太明白:

在你的仓库里分别新建两个分支
从你的仓库直接提交PR到这个仓库的main,提交时选择你的仓库对应的分支。

图片

这里我好像并不能在提交PR是选择新的分支。 比如我有一个tuteng0915/ChuanhuChatGPT::tt/log,我该如何提交到GaiZhenbiao/Ch....GPT::tt/log呢? 在GaiZhenbiao仓库里我该如何进行新建分支的操作?还是说我提交到我的其他分支比如tt/ui?

Keldos-Li commented 1 year ago

额,可能是我没讲清楚。你没法在我们的仓库中新建分支。

我的意思是,”从你的仓库直接提交PR到这个仓库的main“,也就是,本来,直接向main分支提PR就可以了,head选择你自己对应的分支,base是我们的main。

(在其他的社区规范中,也可能别人有一个”develop“分支,会要求你们向develop分支提交PR)

前面给你开分支是因为太乱了。所以我自己给你先理掉了。(一般情况下给别人提PR别人不会专门为你开分支)

(我看你怎么又把apikey提交上去了……

tuteng0915 commented 1 year ago

ok 我理解了,也是说:

如果我是这个项目的管理者,我该每做一个feature单开一个branch,然后项目内提PR merge到master。

我现在Fork了这个项目,那么我就在我的仓库里每做一个feature单开一个branch然后同样在这个项目内提PR merge到master

然后PR是针对branch而言的,而非commit,所以我在开着一个PR的情况下,在merge之前,是可以继续往里commit的

Keldos-Li commented 1 year ago

然后PR是针对branch而言的,而非commit,所以我在开着一个PR的情况下,在merge之前,是可以继续往里commit的

这是正确的。


至于上面对于项目的理解,说实话不同的管理团队会采取不同的做法……

一般来说,main(master)中是保证当前最稳定可用的代码的,一般不会直接往main中提交。

大部分项目会至少有一个开发分支。可能叫develop,dev,feat,v2.3.3……

为了保证main的可用性,可能许多开发者会在develop分支上提交代码。同时,突然我发现了一个bug,所以我新建并在hotfix:xxx上完成了我的修复,然后我将hotfix:xxx合并进develop(或者,直接合并进main,视bug严重与否);当develop分支得到检验测试没问题后,我们再将它合并入main(然后给main打一个新tag)。

至于要不要为feat单开分支,我的习惯是要,当然也有不单开的。一般个人项目不开问题不大,但团队开发开独立分支可以减少冲突。

对于项目管理者而言,完全可以直接pull其他分支执行合并,不一定需要提交pull request。github上的这个只是一个request,“请求你们用用我的代码吧”……一般而言更适用于外部贡献者。对于团队或管理者来说,也可以不需要这一步……但多一步代码审核也不错。

我可能并没有讲清楚,可以看看git手册。

tuteng0915 commented 1 year ago

由于涉及的feat已悉数提交PR,close