---
layout: single
title:  "基于 ChatGLM3 8k 和 32k 的文档问答对比"
date:   2023-12-06 08:00:00 +0800
categories: [AI 与大模型, 操作系统]
tags: [GPT, ChatGLM3, ChatGLM3-6B-32K, bge-base-zh]
---

## 文档

这里使用的文档是：`合作方人员出勤及结算管理信息化支撑规则`

```
一、出勤打卡
出勤打卡包括：正常出勤打卡、出差打卡、外出打卡、加班打卡。

1. 正常出勤打卡：指正常的出勤办公打卡。
（1）全天出勤打卡：上班打卡：8点30分之前打卡。下班打卡：17点30分之后打卡。
（2）半天出勤打卡。上午打卡时间段：8点30分之前、12点之后。下午时间段：13点之前，17点30分之后。
（3）打卡(考勤机或企业微信打卡)形式按部门要求为准，最小半天为统计单位。

2. 出差打卡：指出差地出勤办公或在途期间打卡。
（1）固定出差地打卡：打卡时间参照第1条正常出勤上下班打卡；无法定位有效范围的找部门管理员修改工作打卡位置。(具体按照各部门要求执行)
（2）出差在途打卡(使用手机外出打卡)。到车站坐车前打外出打卡一次，到达目的地后打外出打卡一次(往返同理)。下午出差的，上午需打正常出勤卡(上午正常出勤须闭环打卡)；上午到达出差地的，下午需打一次外出打卡或上下班打卡。

3. 外出打卡：指外出办事打卡。提外出申请后，可以打外出卡，打外出卡时间需在申请时间内：
（1）半天外出：如外出时间在上午(12点前) 或者下午(12点后)，则另外半天需正常出勤打卡。
（2）跨12点外出：如外出跨度期间包含12点，则12点前、12点后分别打外出卡即可记为合格出勤。

4. 加班打卡：指法定节假日加班打卡。
（1）加班打卡：不设置固定上下班打卡要求，但必须形成打卡闭环，加班时间超过8小时即视为全天出勤，超过4小时但不足8小时视为半天出勤，不足4小时视为未出勤。
（2）与加班申请比对：加班时长与申请时长对比，取小的一方数值。如加班8小时以上，但申请4小时，则统计出勤半天。

二、出勤申请审批
出勤申请审批包括：补卡、加班、请假、出差、外出采用企业微信审批，审批层级由各部门自定。特别说明：不符流程的申请、审批，按照无效处理，考勤视为未出勤。

1. 补卡申请：
（1）补卡次数：漏打、异常打卡可申请补卡(直接在当日打卡记录中申请补卡)，每月补卡次数不超过2次，超过部分补录无效。
（2）补卡时间：补卡需要在3天内(从缺勤当日起算)提交申请，超出时限视为无效。

2. 加班申请：
（1）申请日期：只可申请节假日加班(正常出勤日延长办公不视为加班)。
（2）加班申请：加班请提前申请，特殊情况可当日申请。加班申请时间大于4小时，小于8小时视为半天；大于等于8小时视为一天；小于4小时系统不计入加班申请。
（3）与加班打卡比对：加班时长与申请时长对比，取小的一方数值。如加班8小时以上，但申请4小时，则统计出勤半天。
（4）特别注意：有打卡记录但无加班申请视为未出勤；出差期间节假日加班，需要提加班申请；外出加班情况，不需额外提加班申请。

3. 请假申请：
（1）申请填报：请假请提前申请，特殊情况可当天发起申请。
（2）申请时间：整天请假：选择开始时间12:00前，结束时间12:00之后自动视为该整天请假；半天请假：选择开始时间12:00点前、结束时间12:00前视为上午半天请假；开始时间和结束时间为12:00点后，视为下午半天请假。
（3）特别注意：请假审批通过，因工作需要未正式休假或者提前回工作岗位的，请按时打卡，同时撤回本次请假申请(系统允许请假单未审批前撤回或审批后撤回)，重新提交和休假时间相符的申请。否则，请假审批和出勤打卡同时存在时，不算做出勤。

4. 出差申请：
（1）申请填报：出差前需要填写出差审批单，审批单时间需包含实际出差时间；只有打卡记录无审批单视为未出勤，只有审批记录无打卡记录视为未出勤。出差未返回，已超过出差申请时长时间段的，需继续提前进行出差申请延期，可以有申请时间重叠，不允许中间有间隔。

5. 外出申请：
（1）申请范围：仅限于济南五区(历下区、市中 区、槐荫区、天桥区、历城区)范围内。不在固定办公地点外出办公时，要申请外出审批，使用外出打卡。
（2）填写申请：“外出事由” 需要填写详细，有必要时需要上传“附件”。

三、报工
1. 报工
（1）报工情况：正常出勤、出差、外出、加班情况均需进行报工，以半天为最小单位。
（2）报工时限：报工人可填写当前提交日期(包含)前7天内报工，超期无法报工。
（3）补报工情况：遇到不可控因素长时间无法报工(例:服务器维护等原因)，会开放固定时限和月份内补报工功能，届时会通过业务部门或企业微信-工作通知应用进行通知! 
（4）报工匹配：匹配合格：出勤打卡与报工审批一致(以半天为最小单位)，为合格报工，纳入结算。匹配异常：有报工无出勤打卡、有出勤打卡无报工均为异常。
费用结算以报工匹配出勤为依据，报工不可矫正。

四、交通费补贴
1. 交通费报销填报
（1）填报时间：交通费报销允许跨月报销，不再设置按月报销的硬性要求。交通费用和出差补助按照审批通过时间计入结算月份(报销月份)。
（2）填报要求：采用企业微信端“交通费用报销单”模板填写，注意车票凭证清晰、无涂改，城市填写到具体的“城市”或“济南七个县/区，上传照片凭证每张不要超过1M。
（3）填报说明：
    1)交通费报销行程必须形成闭环，即第一段行程起点城市与最后一段行程终点城市形成往返大闭环。
    2)一份报销单即报销一次闭环行程，多个闭环分开报销，以免费用统计出错；闭环内如果首尾城市不一致(如从济南出发但返程回家情况)，请在“特殊情况说明”中备注。
    3)单趟行程内如发生换乘只记录该趟行程出发、目的城市信息即可，但需上传完整票据凭证。
    4)通过“添加明细”依次记录每段行程。
（4）审批人：审批层级(审批人)按部门要求选择。
（5）出差行程闭环样式说明：出差单程车票凭证的起点终点为以下三种情况之一：
    1)base地/家--出差地。
    2)出差地1--出差地2。此情况只适用于出差期间转另外地点出差。
    3)出差地—-base地/家。由base地或家出发，最终又回到base地或家，即形成了一个闭环。

2. 交通费报销填报提交时校验问题情况
（1）如校验未形成行程闭环，则不允许提交，并提示：行程未形成闭环，请填写完整后提交。
（2）如果存在出差报销时间不在申请出差时间内，则不允许提交。提示：本次报销时间未包含在申请出差段内，请处理后提交。
（3）如校验本次报销时间段内已存在提交的出差报销单，则提示：该报销时间段内已存在填报单据，不可重复报销。
（4）校验大闭环内到达、出发城市是否衔接，即上一段的到达城市应是下一段的出发城市，否则提示：报销单内到达、出发城市不衔接，请调整后提交!

五、差旅补贴
出差补助规则：按照公司不同地区补助标准执行(当前执行标准)
（1）划分1档(360元/天)、2档(280元/天)、3档地区(240元/天)。
（2）以中午12:00为分界，出发时(从属地化城市出发到外地)，启程票面时间早于中午12:00(包含)则按照出差城市补助标准1天计算；晚于中午12:00则按照出差城市半天计算。
（3）返程时(返回属地化城市)，按照实际到达时间计算(有延误的需在交通费报销单提交特殊情况说明或上传网站、现场照片)，中午12点(不包含)之前到达按出发城市补助半天，12点(包含)之后到达按出发城市补助一天。
（4）外地出差期间再次出差去外地的，按照中午12点为界，12点(不包含)之前到达另一地区则各算半天，12点(包含)之后到达则按前一个出差地算整天补助。
（5）以第一段行程起点城市和最后一段行程终点城市均视为属地化城市，属地化城市期间不计算补贴费用(针对出差申请期间返回属地化城市情况)。

六、结算矫正
每月8日之后系统可生成上月合作方结算预月报；在正式提交结算月报前，部门管理员可根据合作方人员出勤打卡补录申请、部门确认情况，进行矫正处理。请注意:部门管理员结算矫正时只允许对有报工但无出勤情况进行矫正，无报工情况无法矫正(具体矫正要求以公司管理制度为准)。一旦结算确认后将无法进行矫正。

七、重点注意事项说明
（1）所有业务审批原则上要求次月8号之前完成审批，请在企业微信端留意各审批进度，以免因审批人延误影响个人实际出勤和费用结算情况。
（2）出勤打卡如有漏打或者异常，于3天内(含当日)及时进行补卡；出勤打卡7天内(含当日)注意及时报工。
（3）因系统允许每人挂多个项目，报工时请确定选择合适的报工项目和合适的审批人。
（4）存在出差、加班、外出事宜注意提前及时申请，不要遗漏；请假期间如提前返回正常办公记得撤销原申请并重新提交与实际出勤相符的申请。
（5）交通费报销单注意填报时要形成闭环，且应在出差申请时间内。
（6）所有出勤相关申请及审批必须在结算本月费用之前完成，否则相应申请和审批无效。
（7）申请审批、出勤打卡、报工必须都符合要求才能形成合格的结算考勤，缺一不可。
（8）出勤、出差、报工、结算如有问题请直接联系部门管理员或业务主管部门专责。
```

## 提示词模板
```
"""
{context}
"""

使用三引号里面的上下文来回答最后的问题。请遵守以下规则：
1、如果上下文没有答案，请使用自己的常识回答问题；
2、如果你不知道答案，就说不知道，不要试图编造答案；
3、要用中文回答问题，不要用英文回答问题；
4、回答问题时，要尽量简短；

问:{question}
答:
```

## 问答详情

| 问 | ChatGLM3-6B（基于 bge-base-zh 构建的知识库） | ChatGLM3-6B-32K（整个文档） |
| --- | --- | --- |
| 每月补卡次数 | 每月补卡次数不超过2次。 | 每月补卡次数不超过2次。 |
| 每天考勤时间 | 每天考勤时间是指一天中进行打卡的时间段，通常包括上班打卡、下班打卡和午休打卡等。具体的时间安排可能因企业和部门的制度不同而有所差异。一般来说，上班打卡时间在8点30分之前，下班打卡时间在17点30分之后，午休打卡时间则根据实际需要进行安排。同时，企业和部门也可能会有自己的加班制度，员工需要按照规定的加班时间进行打卡。 | 正常出勤打卡的上班时间为早上8点30分之前，下班时间为下午5点30分之后。半天出勤打卡的上午打卡时间段为早上8点30分之前和下午12点之后，下午时间段为下午1点之前和下午5点30分之后。全天出勤打卡的上班时间为早上8点30分之前，下班时间为下午5点30分之后。具体打卡时间按部门要求为准。 |
| 如何报工 | 报工是指在一定时间内，对员工的工作进行汇总统计，包括正常出勤、出差、外出、加班等情况。在企业中，报工是非常重要的一环，它关系着员工的工资结算和绩效考核。<br>在济南五区（历下区、市中区、槐荫区、天桥区、历城区）范围内，员工外出时需要申请外出审批，并使用外出打卡。报工时，员工需要填写当前提交日期前7天内报工，超期无法报工。在报工过程中，需要匹配合格的出勤打卡和报工审批，否则为异常。同时，报工不可矫正。<br>此外，在交通费和补贴方面，员工需要按照企业规定，使用企业微信端“交通费用报销单”模板进行填报。交通费报销允许跨月报销，不再设置按月报销的硬性要求。<br>在报工、请假、加班、出差等情况下，员工需要按时提交申请，并在规定时间内完成审批。特别注意的是，有打卡记录但无加班申请视为未出勤；出差期间节假日加班，需要提加班申请；外出加班情况，不需额外提加班申请。<br>总之，报工是企业对员工工作的一种管理和考核方式，员工需要按照规定的时间和流程进行报工，确保信息的准确性和完整性。 | 报工包括正常出勤、出差、外出、加班情况，以半天为最小单位。报工人可填写当前提交日期(包含)前7天内报工，超期无法报工。报工匹配：匹配合格：出勤打卡与报工审批一致(以半天为最小单位)，为合格报工，纳入结算。匹配异常：有报工无出勤打卡、有出勤打卡无报工均为异常。 |
| 出差济南一天补助多少钱 | 济南一天的出差补助标准是：<br>1档地区（360元/天）<br>2档地区（280元/天）<br>3档地区（240元/天）<br>具体补助标准会根据公司不同地区的政策进行执行。同时，补助计算也会受到出发时间、到达时间等因素的影响。 | 出差济南一天补助240元。 |
| 请假审批必须形成闭环 | 请假审批必须形成闭环，这是因为在报工过程中，需要匹配出勤打卡和报工审批，以确定员工的工作情况。如果请假审批没有形成闭环，那么在报工时会出现异常，无法正确匹配出勤打卡和报工审批，从而导致工资结算出现错误。<br>因此，在请假审批通过后，员工需要按时进行报工，并且请假审批和出勤打卡必须保持一致。如果员工请假期间没有进行报工，那么在请假结束后，需要及时补报工，并确保请假审批和出勤打卡形成闭环。 | 请假审批必须形成闭环，闭环是指请假申请的开始时间和结束时间之间存在连续的时间段，这个时间段内员工处于休假状态。如果请假审批没有形成闭环，那么员工的出勤记录将不被认可，无法进行费用结算。 |
| 正常出勤打卡的时间要求是什么 | 正常出勤打卡的时间要求如下：<br>全天出勤打卡：上班打卡：8点30分之前打卡。下班打卡：17点30分之后打卡。<br>半天出勤打卡：上午打卡时间段：8点30分之前、12点之后。下午时间段：13点之前，17点30分之后。<br>打卡（考勤机或企业微信打卡）形式按部门要求为准，最小半天为统计单位。 | 正常出勤打卡的时间要求如下：<br>全天出勤打卡：上班打卡：8点30分之前打卡。下班打卡：17点30分之后打卡。<br>半天出勤打卡。上午打卡时间段：8点30分之前、12点之后。下午时间段：13点之前，17点30分之后。<br>打卡(考勤机或企业微信打卡)形式按部门要求为准，最小半天为统计单位。 |
| 报工的要求和流程是什么 | 报工的要求和流程如下：<br><b>报工要求：</b><br>1. 正常出勤、出差、外出、加班情况均需进行报工。<br>2. 报工时限：报工人可填写当前提交日期（包含）前7天内报工，超期无法报工。<br>3. 补报工情况：遇到不可控因素长时间无法报工（例：服务器维护等原因），会开放固定时限和月份内补报工功能，届时会通过业务部门或企业微信-工作通知应用进行通知！<br><b>报工流程：</b><br>1. 出勤（申请审批）：<br>申请范围：仅限于济南五区（历下区、市中区、槐荫区、天桥区、历城区）范围内。不在固定办公地点外出办公时，要申请外出审批，使用外出打卡。<br>填写申请：“外出事由” 需要填写详细，有必要时需要上传“附件”。<br>报工二阶段二：报工①报工情况：正常出勤、出差、外出、加班情况均需进行报工，以半天为最小单位。报工时限：报工人可填写当前提交日期（包含）前7天内报工，超期无法报工。<br>报工匹配：匹配合格：出勤打卡与报工审批一致（以半天为最小单位），为合格报工，纳入结算。匹配异常：有报工无出勤打卡、有出勤打卡无报工均为异常。<br>2. 交通费&补贴：<br>交通费报销填报-1：①填报时间：交通费报销允许跨月报销，不再设置按月报销的硬性要求。交通费用和出差补助按照审批通过时间计入结算月份(报销月份)。<br>填报要求：采用企业微信端“交通费用报销单”模板填写，注意车票凭证清晰、无涂改，城市填写到具体的“城市”或“济南七个县/区”，上传照片凭证每张不要超过1M。<br>填报说明：1）交通费报销行程必须形成闭环，即第一段行程起点城市与最后一段行程终点城市形成往返大闭环。 2）一份报销单即报销一次闭环行程，多个闭环分开报销，以免费用统计出错；闭环内如果首尾城市不一致（如从济南出发但返程回家情况），请在“特殊情况说明”中备注。<br>3. 交通费&补贴：交通费报销填报-2：<br>填报说明：3）单趟行程内如发生换乘只记录该趟行程出发、目的城市信息即可，但需上传完整票据凭证。4）通过“添加明细”依次记录每段行程。<br>补卡时间：补卡需要在3天内（从缺勤当日起算）提交申请 ，超出时限视为无效。<br>4. 加班申请：<br>申请日期：只可申请节假日加班（正常出勤日延长办公不视为加班）。加班申请：加班请提前申请，特殊情况可当日申请。加班申请时间大于4小时，小于8小时视为半天；大于等于8小时视为一天；小于4小时系统不计入加班申请。与加班打卡比对：加班时长与申请时长对比，取小的一方数值。如加班8小时以上，但申请4小时，则统计出勤半天。<br>5. 请假申请：<br>申请填报：请假请提前申请，特殊情况可当天发起申请。申请时间：整天请假：选择开始时间12:00前，结束时间12:00之后自动视为该整天请假；半天请假：选择开始时间12:00点前、结束时间12:00前视为上午半天请假；开始时间和结束时间为 12:00点后，视为下午半天请假。<br>6. 出差申请：<br>申请填报：出差前需要填写出差审批单，审批单时间需包含实际出差时间；只有打卡记录无审批单视为未出勤，只有审批记录无打卡记录视为未出勤。<br>特别说明：不符流程的申请、审批，按照无效处理，考勤视为未出勤。 | 报工的要求和流程如下：<br>报工情况：正常出勤、出差、外出、加班情况均需进行报工，以半天为最小单位。<br>报工时限：报工人可填写当前提交日期(包含)前7天内报工，超期无法报工。<br>补报工情况：遇到不可控因素长时间无法报工(例：服务器维护等原因)，会开放固定时限和月份内补报工功能，届时会通过业务部门或企业微信-工作通知应用进行通知！<br>报工匹配：匹配合格：出勤打卡与报工审批一致(以半天为最小单位)，为合格报工，纳入结算。匹配异常：有报工无出勤打卡、有出勤打卡无报工均为异常。<br>费用结算以报工匹配出勤为依据，报工不可矫正。<br>以上是报工的要求和流程。 |
| QQ | QQ是一款中国的即时通讯软件，提供在线聊天、语音通话、视频聊天、在线游戏等功能，于1999年发布。目前拥有众多用户，成为了中国最具影响力的互联网通讯软件之一。 | QQ是一款即时通讯软件，用户可以通过它与好友进行文字、语音、视频聊天。 |

### ChatGLM3-6B ✚ 知识库（📌 上下文信息缺失）
![](/images/2023/ChatGLM/knowledge-qa.jpg)

### ChatGLM3-6B-32K ✚ 完整文档（📌 更精准）
![](/images/2023/ChatGLM/document-qa.png)


## 量化精度测试
### 总结

| 模型 | 序列长度 | 量化精度 | 显存（GB） | 速度（字符数/秒） |
| --- | ---: | --- | ---: | --- |
| ChatGLM3-6B     |  8k | FP16       |  14 | 29.35 |
| ChatGLM3-6B     |  8k | LLM.int8   |   8 | 15.90 🐢🐢 |
| ChatGLM3-6B     |  8k | INT8       | 7.5 | &nbsp; 4.90 🐢🐢🐢🐢🐢🐢 |
| ChatGLM3-6B-32K | 32k | FP16       |  14 | 30.52 |
| ChatGLM3-6B-32K | 32k | LLM.int8   |   8 | 15.49 🐢🐢 |
| ChatGLM3-6B-32K | 32k | INT8       | 7.5 | &nbsp; 4.79 🐢🐢🐢🐢🐢🐢 |

📌 量化精度 FP16 时，输入序列长度最多 5600 个字符（汉字）；否则，CUDA out of memory.

### 测试脚本（Python）

安装依赖包

```shell
pip install openai typer
```

代码 `llmtest.py`

```py
import time
import openai
import typer

app = typer.Typer()

@app.command()
def main(api_base: str = 'http://172.16.33.66:8000/v1', 
         api_key: str = 'NULL', 
         prompt: str = '你是谁', 
         model: str = 'chatglm3-6b', 
         max_tokens: int = 256, 
         temperature: float = 0.7, 
         top_p: float = 0.95):
    openai.api_base = api_base
    openai.api_key = api_key

    begin_time = time.time()
    response = openai.Completion.create(
        model=model,
        prompt=prompt,
        max_tokens=max_tokens,
        temperature=temperature,
        top_p=top_p
    )   
    end_time = time.time()

    text = response.choices[0].text

    print(f'📝 生成的文本: {text}')
    print(f'🚀 总字符数: {len(text)} 每秒字符数: {len(text)/(end_time-begin_time):.2f}') 

if __name__ == "__main__":
    app()
```

执行脚本

```shell
python llmtest.py --prompt "写一篇500字的小说" --max-tokens=8000
python llmtest.py --prompt "写一篇500字的小说" --max-tokens=32000 --model chatglm3-6b-32k
```

### 测试脚本（Shell）
```shell
#!/bin/bash

start=$(date +%s.%N)
response=$(curl -s http://172.16.33.66:8000/v1/completions \
    -H "Content-Type: application/json" \
    -d '{
        "model": "chatglm3-6b",
        "prompt": "写一篇100字的玄幻小说",
        "temperature": 0.7,
        "max_tokens": 4096
    }')
end=$(date +%s.%N)
runtime=$(echo "$end - $start" | bc)

echo "$response\n\n"

text=$(echo $response | tr -d '[:cntrl:]' | jq -r '.choices[0].text')
tokens=$(echo $response | tr -d '[:cntrl:]' | jq '.usage.completion_tokens')

#text=$(echo $response | grep -oP '(?<=text":").*?(?=",")')
#tokens=$(echo $text | wc -m)
tokens_per_second=$(echo "$tokens / $runtime" | bc)

echo "Execution time: $runtime"
echo "Text: $text"
echo "Completion tokens: $tokens"
echo "Tokens per second: $tokens_per_second"
```

- [jq parse error w.r.t control characters](https://github.com/jqlang/jq/issues/1049)
- [parse error: Invalid string: control characters from U+0000 through U+001F must be escaped](https://qiita.com/re-sasaki/items/7d34109cf209a8ac753c)

### FP16

|      | ChatGLM3-6B |	ChatGLM3-6B-32k |
| ---- | ----: | ----: |
|      | 27.43 | 29.61 |
|      | 31.30 | 30.86 |
|      | 32.99 | 30.62 |
|      | 27.76 | 31.58 |
|      | 27.85 | 31.43 |
|      | 29.51 | 30.81 |
|      | 28.91 | 29.49 |
|      | 28.43 | 29.80 |
|      | 30.01 | 30.47 |
| 平均 | 29.35 | 30.52 |

### LLM.int8 (FP16+INT8)

|      | ChatGLM3-6B |	ChatGLM3-6B-32k |
| ---- | ----: | ----: |
|      | 16.49 | 15.38 |
|      | 15.73 | 15.53 |
|      | 16.66 | 14.82 |
|      | 15.76 | 16.33 |
|      | 15.39 | 16.04 |
|      | 15.10 | 16.02 |
|      | 14.96 | 16.11 |
|      | 17.01 | 15.36 |
|      | 15.98 | 13.79 |
| 平均 | 15.90 | 15.49 |

### INT8

|      | ChatGLM3-6B |	ChatGLM3-6B-32k |
| ---- | ----: | ----: |
|      | 4.84 | 4.61 |
|      | 4.74 | 4.87 |
|      | 5.11 | 4.88 |
| 平均 | 4.90 | 4.79 |
