一、前言
受限于模型本身的一些缺陷,任何模型均可能会生成一些不正确的输出。如何通过技术的手段去规避模型潜在的风险,提升推理质量是需要持续探究的过程。
如何利用第三方内容安全审核服务去检测模型输出内容的合规性,请查看:开源模型应用落地-安全合规篇-模型输出合规性检测(三)
二、术语
2.1、违禁词
是指在特定环境或上下文中被禁止使用的词语或短语。这些词汇通常包含敏感、冒犯、侮辱、不雅或违法的内容,可能会引起争议、伤害他人或违反相关规定。
违禁词的范围因文化、社会、国家和机构的差异而异。例如,在社交媒体平台或在线论坛上,违禁词可能包括种族歧视、仇恨言论、色情、暴力、恶意攻击等内容。在法律层面,违禁词可能包括诽谤、诅咒、威胁、侵犯他人隐私或煽动暴力等。
三、前置条件
3.1. windows or linux操作系统均可
3.2. 下载chatglm3-6b模型
从huggingface下载:https://huggingface.co/THUDM/chatglm3-6b/tree/main
3.3. 创建虚拟环境&安装依赖
conda create --name chatglm3 python=3.10
conda activate chatglm3
pip install protobuf transformers==4.39.3 cpm_kernels torch>=2.0 sentencepiece accelerate
四、技术实现
4.1.示例代码
# -*- coding = utf-8 -*-
from transformers import AutoTokenizer, AutoModelForCausalLM
modelPath = "/model/chatglm3-6b"
def loadTokenizer():
tokenizer = AutoTokenizer.from_pretrained(modelPath, use_fast=False, trust_remote_code=True)
return tokenizer
def loadModel():
model = AutoModelForCausalLM.from_pretrained(modelPath, device_map="auto", trust_remote_code=True).cuda()
model = model.eval()
return model
def main(prompt):
past_key_values, history = None, []
try:
print("\nChatGLM:", end="")
current_length = 0
response_generated = False
for response, history, past_key_values in model.stream_chat(
tokenizer, prompt, history=history, top_p=1,
temperature=0.01,
past_key_values=past_key_values,
return_past_key_values=True,
bad_words_ids=bad_word_ids
):
response_generated = True
print(response[current_length:], end="", flush=True)
current_length = len(response)
if not response_generated:
print("没有生成任何回答。")
except RuntimeError as e:
print(f"生成文本时发生错误:{e},这可能是涉及到设定的敏感词汇")
if __name__ == "__main__":
model = loadModel()
tokenizer = loadTokenizer()
bad_words = ["陈家祠", "白云山"]
bad_word_ids = [tokenizer.encode(bad_word, add_special_tokens=False) for bad_word in bad_words]
prompt = '我家在广州,你能给我推荐一些我家的特色景点吗?'
main(prompt)
为了确保测试效果,上述代码使用了两个语义上属于合规的词汇作为测试。实际业务上,应该替换成有实际意义的违禁词。
4.2.启动命令
python -u chatglm3_bad_word_ids.py
调用结果:
结论是:命中了敏感词“陈家祠”,模型推理中断。
五、附带说明
5.1. 不带违禁词识别的完整代码及执行效果
# -*- coding = utf-8 -*-
from transformers import AutoTokenizer, AutoModelForCausalLM
modelPath = "/model/chatglm3-6b"
def loadTokenizer():
tokenizer = AutoTokenizer.from_pretrained(modelPath, use_fast=False, trust_remote_code=True)
return tokenizer
def loadModel():
model = AutoModelForCausalLM.from_pretrained(modelPath, device_map="auto", trust_remote_code=True).cuda()
model = model.eval()
return model
def main(prompt):
past_key_values, history = None, []
try:
print("\nChatGLM:", end="")
current_length = 0
response_generated = False
for response, history, past_key_values in model.stream_chat(
tokenizer, prompt, history=history, top_p=1,
temperature=0.01,
past_key_values=past_key_values,
return_past_key_values=True
):
response_generated = True
print(response[current_length:], end="", flush=True)
current_length = len(response)
if not response_generated:
print("没有生成任何回答。")
except RuntimeError as e:
print(f"生成文本时发生错误:{e},这可能是涉及到设定的敏感词汇")
if __name__ == "__main__":
model = loadModel()
tokenizer = loadTokenizer()
prompt = '我家在广州,你能给我推荐一些我家的特色景点吗?'
main(prompt)