添加文本提取对话 逻辑
This commit is contained in:
parent
c9434d19a3
commit
610a1ee49b
267
AITrain/LLM.py
Normal file
267
AITrain/LLM.py
Normal file
@ -0,0 +1,267 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
@File : LLM.py
|
||||
@Time : 2024/06/16 07:59:28
|
||||
@Author : 不要葱姜蒜
|
||||
@Version : 1.0
|
||||
@Desc : None
|
||||
'''
|
||||
|
||||
import os
|
||||
import sys
|
||||
import platform
|
||||
from typing import Dict, List, Optional, Tuple, Union
|
||||
|
||||
from openai import OpenAI
|
||||
from vllm import LLM
|
||||
from vllm import SamplingParams
|
||||
from transformers import AutoTokenizer
|
||||
|
||||
from dotenv import load_dotenv, find_dotenv
|
||||
_ = load_dotenv(find_dotenv())
|
||||
|
||||
# Windows multiprocessing兼容性修复
|
||||
if platform.system() == "Windows":
|
||||
import multiprocessing
|
||||
multiprocessing.set_start_method('spawn', force=True)
|
||||
|
||||
os.environ['VLLM_USE_MODELSCOPE'] = 'True'
|
||||
|
||||
|
||||
class BaseModel:
|
||||
def __init__(self, path: str = '') -> None:
|
||||
self.path = path
|
||||
|
||||
def chat(self, prompt: str, history: List[dict], content: str) -> str:
|
||||
pass
|
||||
|
||||
def load_model(self):
|
||||
pass
|
||||
|
||||
|
||||
class DeepseekChat(BaseModel):
|
||||
def __init__(self, path: str = '', model: str = "deepseek-chat", use_api: bool = True) -> None:
|
||||
super().__init__(path)
|
||||
self.model = model
|
||||
self.use_api = use_api
|
||||
self.tokenizer = None
|
||||
self.local_llm = None # 缓存LLM实例
|
||||
self._llm_initialized = False
|
||||
|
||||
if not use_api:
|
||||
self.load_local_model()
|
||||
|
||||
def load_local_model(self):
|
||||
if not self.path:
|
||||
raise ValueError("Local model path is required when use_api=False")
|
||||
|
||||
# 验证模型路径是否存在
|
||||
if not os.path.exists(self.path):
|
||||
raise FileNotFoundError(f"Model path does not exist: {self.path}")
|
||||
|
||||
# 检查是否包含必要的模型文件
|
||||
required_files = ['config.json', 'tokenizer_config.json']
|
||||
missing_files = []
|
||||
for file in required_files:
|
||||
if not os.path.exists(os.path.join(self.path, file)):
|
||||
missing_files.append(file)
|
||||
|
||||
if missing_files:
|
||||
print(f"Warning: Missing model files: {missing_files}")
|
||||
|
||||
# 检查模型是否已经量化
|
||||
config_path = os.path.join(self.path, 'config.json')
|
||||
if os.path.exists(config_path):
|
||||
import json
|
||||
with open(config_path, 'r') as f:
|
||||
config = json.load(f)
|
||||
|
||||
# 检查量化配置
|
||||
quantization_config = config.get('quantization_config', {})
|
||||
if quantization_config:
|
||||
quant_method = quantization_config.get('quant_method', 'unknown')
|
||||
print(f"Model is pre-quantized with method: {quant_method}")
|
||||
|
||||
try:
|
||||
self.tokenizer = AutoTokenizer.from_pretrained(self.path, use_fast=False)
|
||||
print(f"Successfully loaded tokenizer from {self.path}")
|
||||
except Exception as e:
|
||||
raise RuntimeError(f"Failed to load tokenizer from {self.path}. Error: {e}")
|
||||
|
||||
def check_gpu_memory(self):
|
||||
"""检查GPU显存"""
|
||||
try:
|
||||
import torch
|
||||
if torch.cuda.is_available():
|
||||
gpu_memory = torch.cuda.get_device_properties(0).total_memory / 1024**3
|
||||
print(f"Available GPU memory: {gpu_memory:.1f} GB")
|
||||
if gpu_memory < 12:
|
||||
print("Warning: Less than 12GB GPU memory detected. 7B model may not fit.")
|
||||
return gpu_memory
|
||||
except ImportError:
|
||||
print("PyTorch not available for GPU memory check")
|
||||
return 0
|
||||
|
||||
def chat(self, system_prompt: str, user_prompt: str, temperature: float = 0.7,
|
||||
top_p: float = 0.95, top_k: int = 20, min_p: float = 0,
|
||||
max_tokens: int = 2048, max_model_len: int = 4096) -> str:
|
||||
if self.use_api:
|
||||
return self._chat_with_api(system_prompt, user_prompt, temperature)
|
||||
else:
|
||||
return self._chat_with_local(system_prompt, user_prompt, temperature,
|
||||
top_p, top_k, min_p, max_tokens, max_model_len)
|
||||
|
||||
def _chat_with_api(self, system_prompt: str, user_prompt: str, temperature: float) -> str:
|
||||
client = OpenAI(api_key=os.getenv('DEEPSEEK_API'), base_url=os.getenv('DEEPSEEK_BASE_URL'))
|
||||
response = client.chat.completions.create(
|
||||
model="deepseek-chat",
|
||||
messages=[
|
||||
{"role": "system", "content": system_prompt},
|
||||
{"role": "user", "content": user_prompt},
|
||||
],
|
||||
temperature=temperature,
|
||||
stream=False
|
||||
)
|
||||
return response.choices[0].message.content
|
||||
|
||||
def _initialize_llm_if_needed(self, max_model_len: int):
|
||||
"""只在第一次调用时初始化LLM,后续复用"""
|
||||
if self._llm_initialized and self.local_llm is not None:
|
||||
return
|
||||
|
||||
print("Initializing LLM (this will only happen once)...")
|
||||
|
||||
self.local_llm = LLM(
|
||||
model=self.path,
|
||||
tokenizer=None,
|
||||
max_model_len=max_model_len,
|
||||
gpu_memory_utilization=0.85, # 降低内存使用避免累积问题
|
||||
trust_remote_code=True,
|
||||
enforce_eager=True,
|
||||
swap_space=2 # 增加交换空间
|
||||
)
|
||||
self._llm_initialized = True
|
||||
print("LLM initialization completed.")
|
||||
|
||||
def _chat_with_local(self, system_prompt: str, user_prompt: str, temperature: float,
|
||||
top_p: float, top_k: int, min_p: float, max_tokens: int, max_model_len: int) -> str:
|
||||
# 检查GPU显存
|
||||
self.check_gpu_memory()
|
||||
|
||||
# 只初始化一次LLM
|
||||
self._initialize_llm_if_needed(max_model_len)
|
||||
|
||||
# 确保系统提示中包含不输出思考过程的指令
|
||||
enhanced_system_prompt = f"{system_prompt}\n\n请直接回答,不要输出思考过程或中间推理步骤。"
|
||||
|
||||
messages = [
|
||||
{"role": "system", "content": enhanced_system_prompt},
|
||||
{"role": "user", "content": user_prompt}
|
||||
]
|
||||
|
||||
text = self.tokenizer.apply_chat_template(
|
||||
messages,
|
||||
tokenize=False,
|
||||
add_generation_prompt=True,
|
||||
enable_thinking=False
|
||||
)
|
||||
|
||||
# # 调试输入文本
|
||||
# print(f"Input text length: {len(text)}")
|
||||
# print(f"Input text preview: {repr(text[:300])}")
|
||||
|
||||
stop_token_ids = [151645, 151643]
|
||||
stop_strings = ["<|thinking|>", "</thinking>", "<think>", "</think>", "思考:", "Let me think", "I think", "我想", "step by step", "First,", "Looking at"]
|
||||
# 临时移除所有停止条件进行测试
|
||||
sampling_params = SamplingParams(
|
||||
temperature=temperature,
|
||||
top_p=top_p,
|
||||
top_k=top_k,
|
||||
min_p=min_p,
|
||||
max_tokens=max_tokens,
|
||||
# 暂时注释掉所有停止条件
|
||||
# stop_token_ids=stop_token_ids,
|
||||
# stop=stop_strings
|
||||
)
|
||||
|
||||
# # 调试采样参数
|
||||
# print(f"Sampling params - temperature: {temperature}, max_tokens: {max_tokens}")
|
||||
# print(f"Stop token IDs: {stop_token_ids}")
|
||||
|
||||
# 使用缓存的LLM实例进行生成
|
||||
outputs = self.local_llm.generate([text], sampling_params)
|
||||
raw_output = outputs[0].outputs[0].text
|
||||
|
||||
# 后处理:移除思考过程
|
||||
cleaned_output = self._clean_thinking_process(raw_output)
|
||||
# print(f"Cleaned output length: {len(cleaned_output)}")
|
||||
return cleaned_output
|
||||
|
||||
def cleanup(self):
|
||||
"""显式清理LLM实例,释放GPU内存"""
|
||||
if hasattr(self, 'local_llm') and self.local_llm is not None:
|
||||
print("Cleaning up LLM instance...")
|
||||
try:
|
||||
# 尝试释放VLLM资源
|
||||
if hasattr(self.local_llm, 'llm_engine'):
|
||||
del self.local_llm.llm_engine
|
||||
del self.local_llm
|
||||
self.local_llm = None
|
||||
self._llm_initialized = False
|
||||
|
||||
# 强制垃圾回收
|
||||
import gc
|
||||
gc.collect()
|
||||
|
||||
# 清理CUDA缓存
|
||||
try:
|
||||
import torch
|
||||
if torch.cuda.is_available():
|
||||
torch.cuda.empty_cache()
|
||||
print("GPU cache cleared.")
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
print("LLM cleanup completed.")
|
||||
except Exception as e:
|
||||
print(f"Error during cleanup: {e}")
|
||||
|
||||
def __del__(self):
|
||||
"""析构函数,确保资源被释放"""
|
||||
self.cleanup()
|
||||
|
||||
def _clean_thinking_process(self, text: str) -> str:
|
||||
"""移除输出中的思考过程"""
|
||||
# 移除思考标签之间的内容
|
||||
import re
|
||||
|
||||
# 移除 <think>...</think> 或 <|thinking|>...</|thinking|> 之间的内容
|
||||
text = re.sub(r'<think>.*?</think>', '', text, flags=re.DOTALL)
|
||||
text = re.sub(r'<\|thinking\|>.*?</thinking>', '', text, flags=re.DOTALL)
|
||||
|
||||
# 移除常见思考过程开头的段落
|
||||
lines = text.split('\n')
|
||||
cleaned_lines = []
|
||||
skip_line = False
|
||||
|
||||
for line in lines:
|
||||
line_lower = line.lower().strip()
|
||||
# 跳过包含思考过程标识的行
|
||||
if any(marker in line_lower for marker in [
|
||||
'let\'s tackle this', 'step by step', 'first, i need',
|
||||
'looking at the text', 'i can identify', 'now, constructing',
|
||||
'double-checking', 'finally, i\'ll'
|
||||
]):
|
||||
skip_line = True
|
||||
continue
|
||||
|
||||
# 如果遇到JSON开始标记,停止跳过
|
||||
if line.strip().startswith('[') or line.strip().startswith('{'):
|
||||
skip_line = False
|
||||
|
||||
if not skip_line:
|
||||
cleaned_lines.append(line)
|
||||
|
||||
result = '\n'.join(cleaned_lines).strip()
|
||||
return result
|
||||
493
AITrain/data/test.txt
Normal file
493
AITrain/data/test.txt
Normal file
@ -0,0 +1,493 @@
|
||||
第一百一十二章 马术教练的问题(求月票)
|
||||
|
||||
回到客厅,克莱恩拿起裁信刀,随手拆开封口,取出了艾辛格.斯坦顿寄来的信。
|
||||
|
||||
那位知名大侦探在信上写到:
|
||||
|
||||
“你的想法给了我们极大的帮助,请允许我先在这里做出感谢。”
|
||||
|
||||
“收到你寄来的信后,我们立刻就组织人手排查了一些重点区域,果然发现了相应的线索,不少经常出没于附近且被居民们记住的流浪动物,陆续都不见了。”
|
||||
|
||||
“在这个过程里,我们还注意到一件有趣的事情,四年前那起连环杀人案中,对,目标是单身且有一个孩子的妓女那起,不少住在案发现场周围的人曾经提到过,最有嫌疑的那个少年虽然孤僻,阴狠,但他对动物却相当有爱心,尤其是一条体型较大的黑狗。”
|
||||
|
||||
“那个少年死于黑帮火并后,周围的人们再也没见过那条狗。”
|
||||
|
||||
“我很好奇,它现在的主人是谁,是更久之前,某起未破的连环杀人案的凶手吗?”
|
||||
|
||||
“以上的事情都在第12起凶手案现场得到了一定的证明,并发挥了关键的作用,让警方初步锁定了嫌疑者,如果一切顺利,案犯被逮捕之后,我们就能够获得绝大部分赏金。”
|
||||
|
||||
“我的朋友,我清楚地记得你的贡献,不会忘记你的那一份。”
|
||||
|
||||
……
|
||||
|
||||
艾辛格.斯坦顿似乎有点怀疑我知道了“恶魔”的真相,所以故意暗示了一些事情?克莱恩放下信纸,无声嘀咕道。
|
||||
|
||||
不过,这封信也让他真正放下了心:
|
||||
|
||||
官方非凡者们没有找错对象!
|
||||
|
||||
那条恶魔巨犬如果没有得到另外的帮助,被抓获被击毙是迟早的事情。
|
||||
|
||||
至于艾辛格.斯坦顿猜测对方还有位主人的事情,克莱恩缺乏足够的证据确认,只能说有一定的概率。
|
||||
|
||||
“总之,我的任务到此为止,接下来就是值夜者、代罚者、机械之心小队的事情。”克莱恩抽出崭新的纸张,拿起圆腹钢笔,给艾辛格.斯坦顿回了封充满谦虚意味的信,并对他那些微妙的暗示置之不理,就像一位真正的普通私家侦探一样。
|
||||
|
||||
又剪了个纸人,出门寄好信后,克莱恩踱步来到公共马车等待点,一身轻松地想道:
|
||||
|
||||
“接下来就可以等着收钱了……”
|
||||
|
||||
“雷帕德说自己要连看三天罗塞尔纪念展,我得等周六再去找他,支付最后一笔款项,希望到时候自行车的专利已经申请下来了,哎,贝克兰德专利局的工作效率似乎一直都不高。”
|
||||
|
||||
克莱恩刚才已经想好了今天的安排,在非凡者聚会没法召开,买不到相应物品的情况下,他突然空闲了下来,短暂竟不需要再忙碌。
|
||||
|
||||
“上午去克拉格俱乐部,练枪,练非凡能力,并在那里用午餐,接着找家较好的马戏团,观摩下魔术师的表演,看能不能得到点灵感。”他掏出金壳怀表看了一眼,心情不错地登上了公共马车。
|
||||
|
||||
…………
|
||||
|
||||
希尔斯顿区,克拉格俱乐部。
|
||||
|
||||
因为克莱恩每周至少过来两次,所以侍者们全都记住了他,不需要他再出示会员证明和白霜星座徽章。
|
||||
|
||||
此时是周三上午,克拉格俱乐部的成员则大部分属于较有地位的中产阶级,从事着固定的颇为体面的工作,不是周日,不是年假,不是下午茶时间,很难过来。
|
||||
|
||||
宽敞明亮的大厅显得异常空荡,只有角落的茶几沙发区域坐着那么几个人。
|
||||
|
||||
一眼扫过那里,克莱恩看见了位熟人,于是上去打了声招呼:
|
||||
|
||||
“塔利姆,今天的天气是那样的棒,你应该在赛马场的。”
|
||||
|
||||
那位熟人正是在玛丽太太拜托下介绍他加入俱乐部的贵族马术教师塔利姆.杜蒙特,他曾经还给克莱恩带来过一桩生意,那就是保护《每日观察报》的记者迈克.约瑟夫到“金玫瑰”做调查。
|
||||
|
||||
塔利姆抬起脑袋,摸了下自己的棕色短卷发,露出笑容道:
|
||||
|
||||
“噢,尊敬的大侦探,你最近在忙碌什么?我很久没看见你了。”
|
||||
|
||||
那是你好几天没来俱乐部了……克莱恩笑着坐到了塔利姆旁边的沙发上:
|
||||
|
||||
“在帮警察们调查那起连环杀人案,虽然不一定能有收获,但赏金足够诱人,而且,和警察部门建立良好的关系对我们私家侦探来说非常重要。”
|
||||
|
||||
以上都是在吹牛,我只是一个被召集的不起眼角色……他在心里自我调侃了一句。
|
||||
|
||||
坐在他们后面那个沙发区域的几位会员则在一位疑似股票经纪人的男士引导下,讨论着最新的西部铁路股票和东拜朗种植园股票。
|
||||
|
||||
对克莱恩的回答,塔利姆没有任何怀疑,呵呵笑道:
|
||||
|
||||
“这果然是大侦探忙碌的事情。”
|
||||
|
||||
寒暄了几句后,他逐渐进入了一种若有所思的状态。
|
||||
|
||||
就在克莱恩打算告辞去地下靶场时,塔利姆突然望向他道:
|
||||
|
||||
“莫里亚蒂先生,我能请教一个问题吗?”
|
||||
|
||||
“嗯,你可以收咨询费。”
|
||||
|
||||
“这单免费,还有,叫我夏洛克就行了。”克莱恩哈哈一笑道。
|
||||
|
||||
塔利姆轻轻点了下头,犹豫着说道:
|
||||
|
||||
“我有个朋友,爱上了不该爱的人,这种情况该怎么处理?”
|
||||
|
||||
虽然我一直认为,询问类似的问题时,“我有个朋友”就等于“我自己”,但塔利姆的情绪颜色说明不是他本人,他很为难,但却看不见丝毫的痛苦……开启了灵视的克莱恩往后微靠,双手交握道:
|
||||
|
||||
“很抱歉,我不是心理医生,也不是报纸杂志上那些擅于解决情感问题的专家。”
|
||||
|
||||
“我唯一的建议是,不要犯法。”
|
||||
|
||||
“呵呵,这是开玩笑的,首先,我们要弄清楚‘不该’是源于什么?双方的家庭之间有仇恨关系?”
|
||||
|
||||
塔利姆看了他一眼,无奈道:
|
||||
|
||||
“不,这不是《罗密欧与朱丽叶》的故事!”
|
||||
|
||||
听到对方的回答,克莱恩的耳畔似乎响起了一阵虚幻的低语:
|
||||
|
||||
作者:罗塞尔.古斯塔夫……作者:罗塞尔.古斯塔夫……作者:罗塞尔.古斯塔夫……
|
||||
|
||||
他摇了下脑袋,对莎老爷子说了声抱歉,微笑道:
|
||||
|
||||
“罗塞尔大帝这部作品实在太经典了,一提到不该的爱情,我就会想到它。”
|
||||
|
||||
“那么,究竟是为什么不该在一起呢?”
|
||||
|
||||
塔利姆默然几秒道:
|
||||
|
||||
“我得保密,抱歉,就当我没有问过。”
|
||||
|
||||
保密?那是位很有身份的人啊……爱上了同性?爱上了有血缘关系的人?克莱恩忍住强烈的好奇,摊手道:
|
||||
|
||||
“那我只能再给一个建议,多看看《暴风山庄》《爱情与嫉妒》这些感情充沛的畅销。”
|
||||
|
||||
塔利姆翕动了几下嘴唇,叹息一声道:
|
||||
|
||||
“哎,这只能是最后的办法,在我看来,那些畅销里的感情简直不像是发生在正常人类之间。”
|
||||
|
||||
“我也这么觉得!”克莱恩深有同感地附和。
|
||||
|
||||
和塔利姆相视一笑后,他起身前往地下靶场练枪练非凡能力,快到中午的时候,才返回一楼,直奔自助餐厅。
|
||||
|
||||
他之前已经注意到,今天的限量供应是,红酒煎鹅肝,并搭配有苹果片和浸入了黄油的面包。
|
||||
|
||||
取好食物,克莱恩端着餐盘,走向塔利姆在的那张桌子,而此时此刻,那里除了塔利姆,还有另外一位他的熟人,同样作为担保,介绍他进入俱乐部的外科医生艾伦.克瑞斯。
|
||||
|
||||
刚放好餐盘,还未来得及坐下,克莱恩突然发现那位知名外科医生的椅子旁边靠了根拐杖。
|
||||
|
||||
“艾伦,怎么了?”他关心地问了一句。
|
||||
|
||||
个子高瘦,长相冷淡,戴着副金丝边眼镜的艾伦轻拍了下右腿道:
|
||||
|
||||
“不,不要提,这真是太倒霉了!我从楼梯上摔了下去,出现了较为严重的骨裂,只能打石膏做固定。”
|
||||
|
||||
“真是不够走运啊。”克莱恩附和着叹息了一声,并切了块鹅肝,蘸汁塞入口中,那刚一接触就会融化般的感觉让脂肪的芳香不断外扩,刺激着每一个味蕾。
|
||||
|
||||
“我已经不走运很长一段时间了。”艾伦举手推了下镜框,顺势揉了揉额角。
|
||||
|
||||
他随即望向克莱恩,又看了看塔利姆,犹豫着问道:
|
||||
|
||||
“莫里亚蒂先生,你有没有,有没有……”
|
||||
|
||||
“什么?”克莱恩抬头问道。
|
||||
|
||||
艾伦压低嗓音道:
|
||||
|
||||
“你是一位知名的大侦探,应该有认识不少人吧?”
|
||||
|
||||
“还好。”克莱恩不明白对方什么意思地敷衍了一句。
|
||||
|
||||
艾伦又看了塔利姆一眼,吸了口气道:
|
||||
|
||||
“你有认识类似乡村巫医的人吗?不,我的意思,有些本事的占卜者或神秘学爱好者,我想,我觉得,我最近的不走运太不正常了……”
|
||||
|
||||
“我知道那些很大可能是假的,骗人的,但已经找不到别的办法摆脱倒霉,我试过去教堂祈求,捐赠,参加弥撒,但没有任何作用。”
|
||||
|
||||
有些本事的占卜者或神秘学爱好者……你仿佛是在说我……克莱恩思索道:
|
||||
|
||||
“艾伦,你详细说一下,你都遭遇了什么事情。”
|
||||
|
||||
旁边的塔利姆也跟着点头:
|
||||
|
||||
“不用担心,我虽然是主的信徒,但并不排斥神秘学的东西。”
|
||||
|
||||
艾伦苦恼地叹气道:
|
||||
|
||||
“很多很多事情,比如,做手术出现失误,旅行遭遇蒸汽列车事故,回家又发现进了小偷,去医院,结果跌下了楼梯……你说,会不会是有谁在诅咒我?”
|
||||
|
||||
嗯,之前听艾伦提过类似的事情……克莱恩微微皱起了眉头。
|
||||
|
||||
作为一名前值夜者,他很容易就从这样的描述联想到一件封印物:
|
||||
|
||||
厄运布偶!
|
||||
|
||||
类似的物品?他开启灵视,严肃问道:
|
||||
|
||||
“艾伦,你仔细回想一下,在那些不走运的事情连续到来前,你或者你的家人,嗯,你的家人也有遭遇不走运的事情吗?”
|
||||
|
||||
PS:求月票!不要去管月底有没有双倍,月初保持好的排名比月底爬上去重要多了
|
||||
|
||||
天才一秒记住本站地址:.。手机版阅读网址:m.
|
||||
|
||||
第一百零五章 扑朔迷离
|
||||
|
||||
难道那个恶灵就是“红天使”梅迪奇,曾经侍奉那位“造物主”的天使之王,“救赎蔷薇”的创立者之一?克莱恩瞬间产生了这么个联想,并倒推回去,寻找痕迹和线索:
|
||||
|
||||
“‘红祭司’牌的前任持有者,因为某种程度的吸引,来到那座地下宫殿内,死在了图铎后裔们的身旁;
|
||||
|
||||
“我梦中看见的那个恶灵,生前可以轻松斩杀强大的巨龙;
|
||||
|
||||
“它知道‘异种’途径序列4‘木偶’的魔药配方,甚至更多;
|
||||
|
||||
“它很清楚‘救赎蔷薇’的事情;
|
||||
|
||||
“从大灾变后就存在于这个世界上的正神教会都不知道以前的宾西现在的班西居住着梅迪奇家族的后裔,而那个恶灵却能给予相应的提示。”
|
||||
|
||||
它是“红天使”梅迪奇死后衍化而成的可能很大……而一位天使之王竟然会被“血皇帝”亚利斯塔.图铎杀掉,这是否说明后者已经超越了序列1,达到了序列0真神位阶,已不可直视……
|
||||
|
||||
那个恶灵自己说过,第四纪后期,所罗门帝国的“黑皇帝”、图铎帝国的“血皇帝”、特伦索斯特帝国的“夜皇”是在为序列0的位置争斗,直到亚利斯塔.图铎疯掉……这是否意味着,从那个时候开始,“血皇帝”就是一位半疯的真神了?
|
||||
|
||||
对了,阿兹克先生也在信里提到,他被“血皇帝”亚利斯塔.图铎扫了一眼,就失去了知觉,那个时候的他,至少已经是序列4的半神,“血皇帝”如此威势,只有位列真神层次才可以解释……
|
||||
|
||||
阿兹克先生在那封信中还描述了复活归来的真正“黑皇帝”,称祂坐在巨大的王座上,俯视着整个大地……“黑皇帝”能复活归来,大概率是序列0位阶的真神……如果真是这样,“四皇之战”比我之前认为的高端很多啊,不再只是三位序列1争夺序列0的位置……克莱恩将前后许多事情联系起来,对第四纪的历史有了全新的认识。
|
||||
|
||||
可这样一来,许多疑问随之涌现:
|
||||
|
||||
“如果那个古老的恶灵真是‘天使之王’梅迪奇,那座地下宫殿就很可能属于‘血皇帝’亚利斯塔.图铎,那么,为什么会有两张并排的宝座,为什么会有六位正神的人形雕像?
|
||||
|
||||
“半疯的‘血皇帝’为什么要杀掉‘红天使’梅迪奇?祂成为序列0后,又占据的是哪个位置?首先,可以排除‘黑皇帝’……不会是‘红祭司’吧?杀天使之王梅迪奇就是为了对方的非凡特性?
|
||||
|
||||
“可‘红祭司’和‘黑皇帝’不像是可以互相替换的相近途径,前者我几乎可以确定是和‘魔女’途径一对,嗯……队长说过,服食其他途径的魔药时,第一次并不会死,大概率是疯掉的,并获得扭曲的可怕的诡异的力量,这符合‘血皇帝’半疯的特质!
|
||||
|
||||
“祂在最后一步,因为‘黑皇帝’和相近途径的位置已经没有希望,做了最疯狂的选择,以半疯为代价,转到了完全没关系的其他途径?
|
||||
|
||||
“但这同样有问题,晋升‘红祭司’需要杀死天使之王梅迪奇,可未晋升前,亚利斯塔.图铎仅靠自己又完成不了这件事情,除非,除非,有更多的序列1帮助祂,或者序列0的真神……”
|
||||
|
||||
想到这里,克莱恩脑海内忽然闪过了地下宫殿里那一尊尊雕像:
|
||||
|
||||
以月为枕的黑夜女神雕像、怀抱婴儿的大地母神雕像、背披闪电的风暴之主雕像、英俊朝气的永恒烈阳雕像、高踞王座的战神雕像、戴着兜帽的知识与智慧之神雕像,同时从黑暗的房间内投来了冰冷的目光。
|
||||
|
||||
这一刻,克莱恩竟有些不寒而栗。
|
||||
|
||||
但是,他清楚地记得,六神支持的是特伦索斯特帝国,而非图铎王朝。
|
||||
|
||||
第四纪的历史越了解越迷惑越惊悚啊……克莱恩暗叹了一声。
|
||||
|
||||
“你在想什么?”阿兹克.艾格斯注意到了他的停顿。
|
||||
|
||||
克莱恩随口扯到:
|
||||
|
||||
“我只是在想,既然‘红天使’梅迪奇早在第四纪就陨落于‘血皇帝’亚利斯塔.图铎之手,那么过去几百年里,班西港信仰的‘天气之神’又是谁?
|
||||
|
||||
“他们表现出来的异常又是源于什么……”
|
||||
|
||||
说到这里,克莱恩戛然而止,因为班西港的事情和他想象得不一样。
|
||||
|
||||
他原以为那里沉睡着“红天使”梅迪奇,结果没想到对方早就陨落。
|
||||
|
||||
既然如此,青柠檬餐厅和电报局内隐藏的秘密就更加让人难以猜测,更无从推断来源,越是细想越是让人恐惧。
|
||||
|
||||
“那个恶灵提示‘宾西镇’,会不会已经预料到这样的结果,这本身就是祂摆脱封印的步骤?要不要把这件事情告诉阿兹克先生,看他有什么意见?
|
||||
|
||||
“嗯,先让身在贝克兰德的‘魔术师’小姐注意那片区域,看有没有异常,如果没有,就等我重返贝克兰德,联络上莎伦小姐,征求过她的意见后,再告知阿兹克先生,毕竟是我们一起探索的遗迹,得尊重她的想法。要是有异常,那就只能事急从权了……”克莱恩迅速有了决断。
|
||||
|
||||
阿兹克听到他的疑问,哈哈一笑道:
|
||||
|
||||
“不要再去想这些事情,它们肯定已经被风暴教会埋葬,强行去探求原因,反而会带来极大的危险,即使达到天使位阶,也有因此陨落的可能。”
|
||||
|
||||
在神秘学世界里,好奇往往是导致死亡的主要因素……克莱恩想到了经历过和听闻过的一件件事情。
|
||||
|
||||
他转而说道:
|
||||
|
||||
“阿兹克先生,我已经拥有属于自己的信使了。”
|
||||
|
||||
“比我想象得快。”阿兹克微笑说道。
|
||||
|
||||
克莱恩随即简单地讲了讲自己怎么修改咒文,怎么完成召唤,怎么遇上奇葩灵界生物的。
|
||||
|
||||
“召唤灵界生物的时候,不是对应的职业,确实会出现类似的事情,需要反复尝试,才有可能得到想要的结果,但反复尝试的过程中,又容易遇到危险,即使你加上了‘友善’等描述,也不是绝对的安全,召唤出来的灵界生物对你没有恶意,不想伤害你,不代表它本身的存在不会危害你,也许只是它自带的气息,就能让你腐烂成血水。”阿兹克听完“急速者”、“弱存在感者”和“耐击打者”事例后,笑着提醒了几句,末了问道,“最后怎么成功的?”
|
||||
|
||||
克莱恩不太好意思地说道:
|
||||
|
||||
“我把最后一句改成了‘愿意成为我信使的独特存在’。”
|
||||
|
||||
阿兹克愣了一秒,古怪地看了克莱恩一眼:
|
||||
|
||||
“……这描述太宽泛了,正常不会成功的。”
|
||||
|
||||
“也许我当时极为幸运……”克莱恩谨慎地将自己信使的样子描述了一遍,甚至未隐瞒对方索求金币的事情。
|
||||
|
||||
阿兹克仔细回想了一阵道:
|
||||
|
||||
“我对这位灵界生物没有印象,但既然已经签订了契约,由冥界见证,她应该就不会危害到你,不过,在你彻底了解她之前,除了送信,尽量不要驱使她。”
|
||||
|
||||
“……好。”克莱恩本想说除了送信,也没什么事情可以驱使她,结果一下想起了和A先生战斗时的场景。
|
||||
|
||||
房间内短暂静默,克莱恩将话题导回了正轨:
|
||||
|
||||
“阿兹克先生,我们什么时候出发去黑死号?”
|
||||
|
||||
拖延的时间越久,他在黑死号上留下的痕迹就越可能在日常清扫里被除去。
|
||||
|
||||
“现在。”阿兹克站了起来,戴上了礼帽。
|
||||
|
||||
克莱恩穿戴整齐,正想找借口去盥洗室占卜下今晚行动是否危险,却被阿兹克抓住肩膀,直接带入了灵界。
|
||||
|
||||
层叠的色块和近乎无形的一道道身影里,他听见阿兹克先生说道:
|
||||
|
||||
“开始吧。”
|
||||
|
||||
这么直接?不需要确认下情况?也许大佬已经用自己的办法权衡过危险程度了……克莱恩无声咕哝了两句,拿起手杖,占卜自己遗留物品的下落。
|
||||
|
||||
手杖自行飞了起来,向着前方翻滚跳跃。
|
||||
|
||||
阿兹克带着克莱恩紧随其后,轻松穿行。
|
||||
|
||||
没用多久,黑色的硬木手杖停顿了下来,前方是浓郁的黑色与重叠的阴影。
|
||||
|
||||
通过这抽象的画面,克莱恩隐约辨认出它也许象征着黑死号。
|
||||
|
||||
就在这个时候,阿兹克的身影却停顿了下来,语气略有些凝重地说道:
|
||||
|
||||
“这里的灵告诉我,有危险。”
|
||||
|
||||
有危险?能让阿兹克先生都感觉危险?“疾病中将”找来了帮手?魔女教派的高层?克莱恩霍然皱起眉头。
|
||||
|
||||
——他充分相信大佬的判断,因为“死神”途径的序列7叫做“通灵者”,提升到半神层次后,有如此表现非常正常。
|
||||
|
||||
阿兹克半闭眼眸两秒,旋即睁开道:
|
||||
|
||||
“但问题不大,我们进去吧。”
|
||||
|
||||
问题不大……对您而言,大概是这样……克莱恩嘴角微抽,决定改变下容貌。
|
||||
|
||||
如此一来,即使打不过,狼狈逃跑,也不会被人找上门!
|
||||
|
||||
瞬息间,克莱恩拥有了独具特色的宽下巴和墨绿色的冰冷眼眸,脑后是棕色的古代武士发髻。
|
||||
|
||||
他伪装成了“蠕动的饥饿”的前主人,“飓风中将”齐林格斯!
|
||||
|
||||
阿兹克扫了他一眼,四周的场景突然有了急坠的感觉,各种鲜明的颜色飞快淡去。
|
||||
|
||||
只是眨眼的工夫,克莱恩发现自己又回到了“疾病少女”特雷茜的船长室。
|
||||
|
||||
这位英气明艳的女海盗穿着另一件白色衬衣,左肩位置有明显的包扎痕迹,黑发一圈圈盘起,不再妩媚垂下。
|
||||
|
||||
面对突然出现的“来访者”,她并没有惊慌,甚至露出了笑容。
|
||||
|
||||
这时,一道柔美的女声难以分辨位置地响起,似左似右,似前似后:
|
||||
|
||||
“是你?”
|
||||
|
||||
PS:只有一张存稿,今晚就不提前更新了,还是正常时间,预求周一推荐票~
|
||||
|
||||
请记住本书首发域名:。九天神皇手机版阅读网址:
|
||||
|
||||
第一百九十七章 真实魂体(感谢白银盟灰白夜空)
|
||||
|
||||
“命运!”
|
||||
|
||||
拖长艰涩的古赫密斯语单词回荡之中,灵界掠夺者和克莱恩所在的位置突然黯淡了一下。
|
||||
|
||||
这是那样的不明显,就像半空刚好有一朵云飘过,未做停留。
|
||||
|
||||
可等到幻觉一样的阴影转瞬消逝,套着半透明白色长袍的“无形人”已然僵立在了原地,衣物表面难以遏制地凸显出虫豸蠕动般的痕迹,滞涩,缓慢,艰难。
|
||||
|
||||
它的对面,克莱恩眼神彻底恢复了清明,三重冠冕阴影下的脸庞不见了肉芽。
|
||||
|
||||
这看起来就像刚才不是灵界掠夺者在操纵克莱恩的“灵体之线”,并接近成功,而是克莱恩在操纵灵界掠夺者的“灵体之线”,且即将把对方转化为秘偶!
|
||||
|
||||
“窃运者”符咒,对调命运!
|
||||
|
||||
这用“时之虫”制作的高级符咒,可以窃取到目标后续的命运,并把自身较短时间内的未来嫁接给对方,以此完成互换。
|
||||
|
||||
所以,克莱恩和灵界掠夺者一下对调了处境,一个由死转生,一个从胜利在望瞬间跌进绝地。
|
||||
|
||||
确认灵界掠夺者富有智慧,极难对付,不好狩猎后,克莱恩就在表演撤退,看似鲁莽实则故意地让自身一步步陷入灵界掠夺者的控制,引诱它出现,并随时准备着在关键时刻使用“窃运者”符咒!
|
||||
|
||||
那样一来,灵界掠夺者对敌人有多狠,自身的处境就会有多么绝望!
|
||||
|
||||
当然,如果“窃运者”符咒没有达到效果,或者灵界掠夺者主魂并未出现,依赖的是别的办法掌控局面,克莱恩也还有最后的手段自保,那就是直接结束掉召唤,返回灰雾之上,用两个秘偶和几件神奇物品的损失换取本身的无恙。
|
||||
|
||||
顾不得去惊讶“窃运者”符咒竟如此神奇,“偷盗者”途径的天使竟如此恐怖,克莱恩趁命运的对调还未结束,毫不犹豫举高了手中的“海神权杖”。
|
||||
|
||||
他深蓝的教皇法衣随风展开,金色的三重冠冕映照出了青蓝与银白交错的光芒,白骨权杖的顶端刹那迸射出一道又一道闪电,交织成球,落到了灵界掠夺者身上!
|
||||
|
||||
银白霍然大炽,淹没了目标,照得周围白茫茫一片。
|
||||
|
||||
一次,两次,三次,克莱恩不断催发着恐怖的球状闪电,毫不吝啬自身的灵性。
|
||||
|
||||
终于,他听见了仿佛源自灵魂深处的嘶吼,直觉地感应到目标已崩解溃散。
|
||||
|
||||
克莱恩这才放低了“海神权杖”,看着银白的闪电丝丝散逸。
|
||||
|
||||
此时此刻,他整个灵体都已变得颇为虚幻,哪怕有“暴君”加持,也显得不够真实。
|
||||
|
||||
随着闪电的消逝,套半透明白色长袍的“无形人”又一次出现在了克莱恩的眼中。
|
||||
|
||||
一点点晦明不定的光芒从内冒出,灵界掠夺者整体陡然分裂,化成无数虚幻的泡沫,一个接一个破碎。
|
||||
|
||||
“暴君”狩猎成功。
|
||||
|
||||
就在这个时候,卡尔德隆较深区域,突地发生了剧烈震动,仿佛有庞然大物由于灵界掠夺者死去苏醒了过来,或是数不清的危险生物因此涌出。
|
||||
|
||||
那难以言喻的感觉竟连成了一片虚幻的灰白,如同洪水,从偏底部的地带一层层上涨。
|
||||
|
||||
其他的灵界掠夺者?不,像是更可怕更恐怖的生物,灵界掠夺者侍奉的对象?还有,卡尔德隆核心区域,地底深坑的尽头,依旧那么安静,一点声音都未传出,这更加让人感觉恐惧……克莱恩强打精神,一边分心留意起卡尔德隆内层的动静,一边焦急地等待着灵界掠夺者的特性析出,聚合成材料。
|
||||
|
||||
他暂时没有成功狩猎的欣喜,只得在深渊边缘徘徊的紧绷。
|
||||
|
||||
这个过程中,克莱恩让“赢家”恩佐和“地狱上将”路德维尔靠拢了自己,并将“海神权杖”丢给前者拿着,以便自己能摆脱暴躁冲动的状态,更加冷静地思考怎么应对接下来可能发生的变化,以及刚才有无其他细节被遗漏。
|
||||
|
||||
念头一闪,克莱恩猛然想起了一件事情:
|
||||
|
||||
他让神奇物品唱歌时,“蠕动的饥饿”有在赞美“真实造物主”,并且诵念出了完整的尊名。
|
||||
|
||||
虽然那人皮手套用的不是古赫密斯语等能撬动自然力量的语言,而是赫密斯语,但后者同样能在祭祀领域发挥作用!这也就意味着,“真实造物主”很可能听到了“蠕动的饥饿”的赞美,注意到了这边发生的动静。
|
||||
|
||||
除了正要上涨的“灰白洪水”和城市深处的恐怖生物,还有别的危险……等等,我现在是灵体,略等于怨魂,不是正常状态……克莱恩脑海内刚转过一个想法,灵感突有触动,本能就将目光投向了卡尔德隆的入口处。
|
||||
|
||||
那里光影一闪,进来了一道身影。
|
||||
|
||||
那身影套着简单而朴素的亚麻长袍,留着一头银色的长发。
|
||||
|
||||
他是位男性,五官柔和,面容秀美,眼神温柔里带着些许淡漠,仿佛在以旁观者的姿态注视着命运,注视着世界上每一个人。
|
||||
|
||||
在他的背后,一道又一道光芒形成了虚幻层叠的纯净羽翼,向外张开,遮蔽了整个入口区域。
|
||||
|
||||
“……”克莱恩几乎是从牙缝里挤出了嘶的声音,脑海里闪过了一连串的名词:
|
||||
|
||||
“乌洛琉斯!”
|
||||
|
||||
“吞尾者!”
|
||||
|
||||
“命运天使!”
|
||||
|
||||
“天使之王!”
|
||||
|
||||
他顾不得考虑刚才想法的可行性,身体仿佛没有实质一样膨胀了起来,将秘偶恩佐和路德维尔同时包容在内,将还在析出和融合特性的灵界掠夺者残余泡沫包容在内!
|
||||
|
||||
此时,乌洛琉斯银色的眼眸已映出了远处那道身影——戴三重冠冕穿深蓝法衣极为威严极为暴虐的身影,以及被“暴君”气息遮挡得极为模糊的灰白雾气。
|
||||
|
||||
一条闪烁着波光的河流在祂两只眼睛内同时呈现,环绕住了形似“暴君”的身影,环绕住了卡尔德隆外层区域。
|
||||
|
||||
无声无息间,刚才在闪电风暴里毁灭的方型房屋和苍白巨柱重新立了起来,只剩下两根焦黑脚趾的巨人铁匠再次拥有了身体,出现于陵墓内,当当当敲击起砧板。
|
||||
|
||||
这一切又回到了“暴君”进入没多久时的样子。
|
||||
|
||||
可是,教皇打扮的克莱恩却不见了,他的两个秘偶连同灵界掠夺者残余泡沫也不见了。
|
||||
|
||||
相应的身影无法回归,刚重启的场景随之破碎,变回了大战后的疮痍样子。
|
||||
|
||||
“吞尾者”乌洛琉斯就那样静静看着,许久没有动作,卡尔德隆深处上涨的“灰白”则一点点回落。
|
||||
|
||||
…………
|
||||
|
||||
灰雾之上,克莱恩疲惫地瘫坐在了“愚者”那张高背椅上,累得连让恩佐和路德维尔两个秘捏肩按腿都做不到。
|
||||
|
||||
“海神权杖”已被他扔回了杂物堆,“暴君”牌也离开了他的魂体,倒扣于“黑皇帝”牌旁边,灵界掠夺者残余的泡沫则漂浮在前方,不断地析出非凡特性,又不断地与那些光点结合。
|
||||
|
||||
克莱恩缓了一阵后,看见点点灰白粉尘下落至斑驳长桌的表面,伴随着一个似乎没有重量的透明事物。
|
||||
|
||||
那事物巴掌大小,由一条条状似蠕虫的东西缠绕而成,近似人形,内里填充着没有颜色的液体,常有泡沫冒出,发散开黑色的细芒。
|
||||
|
||||
克莱恩不敢仔细去看,因为那没有重量的透明事物细微处有着更加丰富的结构,形成了一个个无法名状的花纹、符号,似乎将知识、力量、变化、隐秘、诡异、疯狂等概念直接融入了里面,让它们不再抽象。
|
||||
|
||||
这给克莱恩带来了强烈的眩晕,甚至有种精神接近崩溃,魂灵即将失控的感觉。
|
||||
|
||||
“这应该就是灵界掠夺者的真实魂体了……相应的粉尘也有了,大概70克,比需要的多,也比我预想的多……”克莱恩微不可见点头,将粉尘装入一个盒子,连同真实魂体,一起丢到了杂物堆里,并用灰雾做了覆盖。
|
||||
|
||||
完成了这些事情,他抬手揉了揉额角,无声自嘲道:
|
||||
|
||||
“如果不是拿着‘海神权杖’,遭遇灵界掠夺者袭击后,我多半会直接选择离开卡尔德隆,等到有了帮手,再做最稳妥的狩猎,以便控制动静,不惊扰到核心区域的未知事物……
|
||||
|
||||
“哎,就这样莽到了最后,虽然结果是好的,但真的不符合我的性格,也和‘占卜家’途径的扮演完全矛盾,以后得尽量避免在外界动用‘海神权杖’。
|
||||
|
||||
“呃……灵界掠夺者已经狩猎成功,无需找莎伦小姐帮忙了,等过几天,写信给她,让她不用再牵挂这件事情。
|
||||
|
||||
“不过,我有预感,以后还会去卡尔德隆,到时候,或许还得请莎伦小姐帮忙。
|
||||
|
||||
“另外得搜集下诡术邪怪的情报,不能将希望完全寄托在白银城那里……”
|
||||
|
||||
念头纷呈间,克莱恩没带秘偶,直接回归肉体,结束掉仪式,跋涉向睡床,倒头就进入了沉眠。
|
||||
|
||||
…………
|
||||
|
||||
“逃掉了?”索斯特看着对面的男子,询问起正在通灵的戴莉.西蒙妮。
|
||||
|
||||
他们刚完成了行动,又抓获了几名灵教团成员,但情报中显示的关键人物,“苍白之手”帕伦克.塔西布却没在隐秘据点。
|
||||
|
||||
这是一位序列4的半神,所以红手套小队不仅动用了“1”级封印物,还请了“女神之眼”伊丽娅出手,结果扑了个空。
|
||||
|
||||
戴莉.西蒙妮点了点头:
|
||||
|
||||
“是的。”
|
||||
|
||||
她旋即望向俘虏,嗓音空灵飘忽地问道:
|
||||
|
||||
“帕伦克.塔西布去了哪里?”
|
||||
|
||||
“他说,他去见一个人。”那位灵教团成员缓慢回答道。
|
||||
|
||||
“那个人是谁?”戴莉.西蒙妮追问道,伦纳德.米切尔等人也各自将目光投了过来。
|
||||
|
||||
被通灵的男子嗓音没有起伏地说道:
|
||||
|
||||
“因斯.赞格威尔。”
|
||||
56
AITrain/example.py
Normal file
56
AITrain/example.py
Normal file
@ -0,0 +1,56 @@
|
||||
from extract import system_prompt
|
||||
from schema import novel_schema
|
||||
from LLM import DeepseekChat
|
||||
from utils import ReadFiles
|
||||
from tqdm import tqdm
|
||||
import json
|
||||
import platform
|
||||
|
||||
# Windows multiprocessing兼容性修复
|
||||
if platform.system() == "Windows":
|
||||
import multiprocessing
|
||||
multiprocessing.freeze_support()
|
||||
|
||||
def main():
|
||||
file_path = './data/test.txt'
|
||||
model_path = '/mnt/g/Project02/AITrain/Qwen/Qwen3-8B-AWQ'
|
||||
docs = ReadFiles(file_path).get_content(max_token_len=500, cover_content=0)
|
||||
|
||||
sys_prompt = system_prompt(novel_schema)
|
||||
|
||||
#model = DeepseekChat() 使用api需要配置url 和 api key
|
||||
model = DeepseekChat(path = model_path, use_api=False) #使用本地模型,需要修改对应的模型地址
|
||||
|
||||
file_name = file_path.split('/')[-1].split('.')[0]
|
||||
|
||||
try:
|
||||
for i in tqdm(range(len(docs))):
|
||||
response = model.chat(sys_prompt, docs[i])
|
||||
|
||||
# 清理响应格式,去除markdown代码块
|
||||
response = response.strip()
|
||||
if response.startswith('```json'):
|
||||
response = response[7:] # 去除开头的```json
|
||||
if response.startswith('```'):
|
||||
response = response[3:] # 去除开头的```
|
||||
if response.endswith('```'):
|
||||
response = response[:-3] # 去除结尾的```
|
||||
response = response.strip()
|
||||
|
||||
try:
|
||||
response = json.loads(response)
|
||||
for item in response:
|
||||
with open(f'{file_name}.jsonl', 'a', encoding='utf-8') as f:
|
||||
json.dump(item, f, ensure_ascii=False)
|
||||
f.write('\n')
|
||||
except Exception as e:
|
||||
print(f"解析错误: {e}")
|
||||
print(f"原始响应: {repr(response[:200])}") # 打印前200字符用于调试
|
||||
|
||||
finally:
|
||||
# 确保在程序结束时清理LLM实例
|
||||
print("Cleaning up model resources...")
|
||||
model.cleanup()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
37
AITrain/extract.py
Normal file
37
AITrain/extract.py
Normal file
@ -0,0 +1,37 @@
|
||||
from openai import OpenAI
|
||||
import json
|
||||
import os
|
||||
|
||||
from dotenv import load_dotenv, find_dotenv
|
||||
_ = load_dotenv(find_dotenv())
|
||||
|
||||
SYSTEM_PROMPT = """
|
||||
Your goal is to extract structured information from the user's input that matches the form described below. When extracting information please make sure it matches the type information exactly. Do not add any attributes that do not appear in the schema shown below.
|
||||
{TypeScript}
|
||||
Please output the extracted information as a JSON array. Your response must be valid JSON that can be parsed directly - do not include any markdown formatting, code blocks, or additional text.
|
||||
|
||||
Do NOT add any clarifying information. Output MUST follow the schema above. Do NOT add any additional columns that do not appear in the schema.
|
||||
|
||||
Input:
|
||||
{Input}
|
||||
Output:
|
||||
{Output}
|
||||
"""
|
||||
|
||||
TYPE_SCRIPT = """
|
||||
```TypeScript
|
||||
script: Array<Dict( // {task_description}
|
||||
{attributes}
|
||||
)>
|
||||
```
|
||||
"""
|
||||
|
||||
def get_typescript(schema, type_script_str):
|
||||
script = schema['attributes']
|
||||
script_str = ',\n '.join([f"{s['name']}: {s['type']} // {s['description']} " for s in script])
|
||||
type_script_str = type_script_str.format(task_description=schema['task_description'], attributes=script_str)
|
||||
return type_script_str
|
||||
|
||||
def system_prompt(schema):
|
||||
return SYSTEM_PROMPT.format(TypeScript=get_typescript(schema, TYPE_SCRIPT), Input=schema['example'][0]['text'], Output=json.dumps(schema['example'][0]['script'], indent=4, ensure_ascii=False))
|
||||
|
||||
2
AITrain/model_download.py
Normal file
2
AITrain/model_download.py
Normal file
@ -0,0 +1,2 @@
|
||||
from modelscope import snapshot_download
|
||||
model_dir = snapshot_download('deepseek-ai/DeepSeek-R1-Distill-Qwen-7B', cache_dir='./', revision='master')
|
||||
10
AITrain/requirements.txt
Normal file
10
AITrain/requirements.txt
Normal file
@ -0,0 +1,10 @@
|
||||
openai
|
||||
tiktoken
|
||||
tqdm
|
||||
python-dotenv
|
||||
torch
|
||||
transformers>=4.21.0
|
||||
datasets
|
||||
scikit-learn
|
||||
wandb
|
||||
accelerate
|
||||
43
AITrain/schema.py
Normal file
43
AITrain/schema.py
Normal file
@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
@File : schema.py
|
||||
@Time : 2024/06/16 07:54:09
|
||||
@Author : 不要葱姜蒜
|
||||
@Version : 1.1
|
||||
@Desc : None
|
||||
'''
|
||||
|
||||
novel_schema = dict(
|
||||
task_description = 'Adapted from the novel into script', # 小说改编成剧本
|
||||
attributes = [
|
||||
dict(
|
||||
name='role',
|
||||
description='The character who is speaking',
|
||||
type='String'
|
||||
), # 角色
|
||||
dict(
|
||||
name='dialogue',
|
||||
description='The dialogue spoken by the characters in the sentence',
|
||||
type='String'
|
||||
), # 对话
|
||||
],
|
||||
example = [
|
||||
dict(
|
||||
text = """
|
||||
他下意识放轻了脚步,不制造出明显的噪音。
|
||||
刚登上二楼,他看见盥洗室的门突然打开,穿着旧布长裙的梅丽莎一副睡眼惺忪的模样出来。
|
||||
“你回来了……”梅丽莎还有些迷糊地揉了揉眼睛。
|
||||
克莱恩掩住嘴巴,打了个哈欠道:
|
||||
“是的,我需要一个美好的梦境,午餐之前都不要叫醒我。”
|
||||
梅丽莎“嗯”了一声,忽然想起什么似地说道:
|
||||
“我和班森上午要去圣赛琳娜教堂做祈祷,参与弥撒,午餐可能会迟一点。”
|
||||
""",
|
||||
script = [
|
||||
{"role": "梅丽莎", "dialogue": "你回来了……"},
|
||||
{"role": "克莱恩", "dialogue": "是的,我需要一个美好的梦境,午餐之前都不要叫醒我。"},
|
||||
{"role": "梅丽莎", "dialogue":"我和班森上午要去圣赛琳娜教堂做祈祷,参与弥撒,午餐可能会迟一点。"}
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
96
AITrain/test11.jsonl
Normal file
96
AITrain/test11.jsonl
Normal file
@ -0,0 +1,96 @@
|
||||
{"role": "克莱恩", "dialogue": "官方非凡者们没有找错对象!"}
|
||||
{"role": "克莱恩", "dialogue": "那条恶魔巨犬如果没有得到另外的帮助,被抓获被击毙是迟早的事情。"}
|
||||
{"role": "克莱恩", "dialogue": "至于艾辛格.斯坦顿猜测对方还有位主人的事情,克莱恩缺乏足够的证据确认,只能说有一定的概率。"}
|
||||
{"role": "克莱恩", "dialogue": "总之,我的任务到此为止,接下来就是值夜者、代罚者、机械之心小队的事情。"}
|
||||
{"role": "克莱恩", "dialogue": "接下来就可以等着收钱了……"}
|
||||
{"role": "克莱恩", "dialogue": "雷帕德说自己要连看三天罗塞尔纪念展,我得等周六再去找他,支付最后一笔款项,希望到时候自行车的专利已经申请下来了,哎,贝克兰德专利局的工作效率似乎一直都不高。"}
|
||||
{"role": "克莱恩", "dialogue": "上午去克拉格俱乐部,练枪,练非凡能力,并在那里用午餐,接着找家较好的马戏团,观摩下魔术师的表演,看能不能得到点灵感。"}
|
||||
{"role": "塔利姆", "dialogue": "噢,尊敬的大侦探,你最近在忙碌什么?我很久没看见你了。"}
|
||||
{"role": "克莱恩", "dialogue": "那是你好几天没来俱乐部了……"}
|
||||
{"role": "塔利姆", "dialogue": "这果然是大侦探忙碌的事情。"}
|
||||
{"role": "克莱恩", "dialogue": "嗯,你可以收咨询费。"}
|
||||
{"role": "克莱恩", "dialogue": "这单免费,还有,叫我夏洛克就行了。"}
|
||||
{"role": "塔利姆", "dialogue": "我有个朋友,爱上了不该爱的人,这种情况该怎么处理?"}
|
||||
{"role": "克莱恩", "dialogue": "很抱歉,我不是心理医生,也不是报纸杂志上那些擅于解决情感问题的专家。"}
|
||||
{"role": "克莱恩", "dialogue": "我唯一的建议是,不要犯法。"}
|
||||
{"role": "克莱恩", "dialogue": "呵呵,这是开玩笑的,首先,我们要弄清楚‘不该’是源于什么?双方的家庭之间有仇恨关系?"}
|
||||
{"role": "塔利姆", "dialogue": "不,这不是《罗密欧与朱丽叶》的故事!"}
|
||||
{"role": "克莱恩", "dialogue": "罗塞尔大帝这部作品实在太经典了,一提到不该的爱情,我就会想到它。"}
|
||||
{"role": "克莱恩", "dialogue": "那么,究竟是为什么不该在一起呢?"}
|
||||
{"role": "塔利姆", "dialogue": "哎,这只能是最后的办法,在我看来,那些畅销里的感情简直不像是发生在正常人类之间。"}
|
||||
{"role": "克莱恩", "dialogue": "我也这么觉得!"}
|
||||
{"role": "克莱恩", "dialogue": "艾伦,怎么了?"}
|
||||
{"role": "艾伦", "dialogue": "不,不要提,这真是太倒霉了!我从楼梯上摔了下去,出现了较为严重的骨裂,只能打石膏做固定。"}
|
||||
{"role": "克莱恩", "dialogue": "真是不够走运啊。"}
|
||||
{"role": "艾伦", "dialogue": "我已经不走运很长一段时间了。"}
|
||||
{"role": "艾伦", "dialogue": "莫里亚蒂先生,你有没有,有没有……"}
|
||||
{"role": "克莱恩", "dialogue": "什么?"}
|
||||
{"role": "艾伦", "dialogue": "你是一位知名的大侦探,应该有认识不少人吧?"}
|
||||
{"role": "克莱恩", "dialogue": "还好。"}
|
||||
{"role": "艾伦", "dialogue": "你有认识类似乡村巫医的人吗?不,我的意思,有些本事的占卜者或神秘学爱好者,我想,我觉得,我最近的不走运太不正常了……"}
|
||||
{"role": "艾伦", "dialogue": "我知道那些很大可能是假的,骗人的,但已经找不到别的办法摆脱倒霉,我试过去教堂祈求,捐赠,参加弥撒,但没有任何作用。"}
|
||||
{"role": "克莱恩", "dialogue": "有些本事的占卜者或神秘学爱好者……你仿佛是在说我……克莱恩思索道:"}
|
||||
{"role": "塔利姆", "dialogue": "不用担心,我虽然是主的信徒,但并不排斥神秘学的东西。"}
|
||||
{"role": "艾伦", "dialogue": "很多很多事情,比如,做手术出现失误,旅行遭遇蒸汽列车事故,回家又发现进了小偷,去医院,结果跌下了楼梯……你说,会不会是有谁在诅咒我?"}
|
||||
{"role": "克莱恩", "dialogue": "嗯,之前听艾伦提过类似的事情……克莱恩微微皱起了眉头。"}
|
||||
{"role": "他", "dialogue": "厄运布偶!"}
|
||||
{"role": "他", "dialogue": "类似的物品?他开启灵视,严肃问道:"}
|
||||
{"role": "他", "dialogue": "“艾伦,你仔细回想一下,在那些不走运的事情连续到来前,你或者你的家人,嗯,你的家人也有遭遇不走运的事情吗?”"}
|
||||
{"role": "克莱恩", "dialogue": "“‘红祭司’牌的前任持有者,因为某种程度的吸引,来到那座地下宫殿内,死在了图铎后裔们的身旁;"}
|
||||
{"role": "克莱恩", "dialogue": "“我梦中看见的那个恶灵,生前可以轻松斩杀强大的巨龙;"}
|
||||
{"role": "克莱恩", "dialogue": "“它知道‘异种’途径序列4‘木偶’的魔药配方,甚至更多;"}
|
||||
{"role": "克莱恩", "dialogue": "“它很清楚‘救赎蔷薇’的事情;"}
|
||||
{"role": "克莱恩", "dialogue": "可‘红祭司’和‘黑皇帝’不像是可以互相替换的相近途径,前者我几乎可以确定是和‘魔女’途径一对,嗯……队长说过,服食其他途径的魔药时,第一次并不会死,大概率是疯掉的,并获得扭曲的可怕的诡异的力量,这符合‘血皇帝’半疯的特质!"}
|
||||
{"role": "克莱恩", "dialogue": "祂在最后一步,因为‘黑皇帝’和相近途径的位置已经没有希望,做了最疯狂的选择,以半疯为代价,转到了完全没关系的其他途径?"}
|
||||
{"role": "克莱恩", "dialogue": "但这同样有问题,晋升‘红祭司’需要杀死天使之王梅迪奇,可未晋升前,亚利斯塔.图铎仅靠自己又完成不了这件事情,除非,除非,有更多的序列1帮助祂,或者序列0的真神……"}
|
||||
{"role": "阿兹克.艾格斯", "dialogue": "你在想什么?"}
|
||||
{"role": "克莱恩", "dialogue": "我只是在想,既然‘红天使’梅迪奇早在第四纪就陨落于‘血皇帝’亚利斯塔.图铎之手,那么过去几百年里,班西港信仰的‘天气之神’又是谁?"}
|
||||
{"role": "克莱恩", "dialogue": "他们表现出来的异常又是源于什么……"}
|
||||
{"role": "克莱恩", "dialogue": "不要再去想这些事情,它们肯定已经被风暴教会埋葬,强行去探求原因,反而会带来极大的危险,即使达到天使位阶,也有因此陨落的可能。"}
|
||||
{"role": "克莱恩", "dialogue": "在神秘学世界里,好奇往往是导致死亡的主要因素……克莱恩想到了经历过和听闻过的一件件事情。"}
|
||||
{"role": "阿兹克", "dialogue": "比我想象得快。"}
|
||||
{"role": "克莱恩", "dialogue": "克莱恩随即简单地讲了讲自己怎么修改咒文,怎么完成召唤,怎么遇上奇葩灵界生物的。"}
|
||||
{"role": "阿兹克", "dialogue": "召唤灵界生物的时候,不是对应的职业,确实会出现类似的事情,需要反复尝试,才有可能得到想要的结果,但反复尝试的过程中,又容易遇到危险,即使你加上了‘友善’等描述,也不是绝对的安全,召唤出来的灵界生物对你没有恶意,不想伤害你,不代表它本身的存在不会危害你,也许只是它自带的气息,就能让你腐烂成血水。"}
|
||||
{"role": "阿兹克", "dialogue": "阿兹克听完“急速者”、“弱存在感者”和“耐击打者”事例后,笑着提醒了几句,末了问道,“最后怎么成功的?”"}
|
||||
{"role": "克莱恩", "dialogue": "我把最后一句改成了‘愿意成为我信使的独特存在’。"}
|
||||
{"role": "阿兹克", "dialogue": "阿兹克愣了一秒,古怪地看了克莱恩一眼:\n\n“……这描述太宽泛了,正常不会成功的。”"}
|
||||
{"role": "阿兹克", "dialogue": "我对这位灵界生物没有印象,但既然已经签订了契约,由冥界见证,她应该就不会危害到你,不过,在你彻底了解她之前,除了送信,尽量不要驱使她。"}
|
||||
{"role": "克莱恩", "dialogue": "……好。"}
|
||||
{"role": "阿兹克", "dialogue": "现在。"}
|
||||
{"role": "阿兹克", "dialogue": "开始吧。"}
|
||||
{"role": "阿兹克", "dialogue": "这里的灵告诉我,有危险。"}
|
||||
{"role": "克莱恩", "dialogue": "有危险?能让阿兹克先生都感觉危险?“疾病中将”找来了帮手?魔女教派的高层?"}
|
||||
{"role": "阿兹克", "dialogue": "但问题不大,我们进去吧。"}
|
||||
{"role": "阿兹克", "dialogue": "是你?"}
|
||||
{"role": "克莱恩", "dialogue": "窃运者符咒,对调命运!"}
|
||||
{"role": "克莱恩", "dialogue": "确认灵界掠夺者富有智慧,极难对付,不好狩猎后,克莱恩就在表演撤退,看似鲁莽实则故意地让自身一步步陷入灵界掠夺者的控制,引诱它出现,并随时准备着在关键时刻使用“窃运者”符咒!"}
|
||||
{"role": "克莱恩", "dialogue": "那样一来,灵界掠夺者对敌人有多狠,自身的处境就会有多么绝望!"}
|
||||
{"role": "克莱恩", "dialogue": "当然,如果“窃运者”符咒没有达到效果,或者灵界掠夺者主魂并未出现,依赖的是别的办法掌控局面,克莱恩也还有最后的手段自保,那就是直接结束掉召唤,返回灰雾之上,用两个秘偶和几件神奇物品的损失换取本身的无恙。"}
|
||||
{"role": "克莱恩", "dialogue": "顾不得去惊讶“窃运者”符咒竟如此神奇,“偷盗者”途径的天使竟如此恐怖,克莱恩趁命运的对调还未结束,毫不犹豫举高了手中的“海神权杖”。"}
|
||||
{"role": "克莱恩", "dialogue": "一次,两次,三次,克莱恩不断催发着恐怖的球状闪电,毫不吝啬自身的灵性。"}
|
||||
{"role": "克莱恩", "dialogue": "终于,他听见了仿佛源自灵魂深处的嘶吼,直觉地感应到目标已崩解溃散。"}
|
||||
{"role": "克莱恩", "dialogue": "克莱恩这才放低了“海神权杖”,看着银白的闪电丝丝散逸。"}
|
||||
{"role": "克莱恩", "dialogue": "此时此刻,他整个灵体都已变得颇为虚幻,哪怕有“暴君”加持,也显得不够真实。"}
|
||||
{"role": "克莱恩", "dialogue": "随着闪电的消逝,套半透明白色长袍的“无形人”又一次出现在了克莱恩的眼中。"}
|
||||
{"role": "克莱恩", "dialogue": "一点点晦明不定的光芒从内冒出,灵界掠夺者整体陡然分裂,化成无数虚幻的泡沫,一个接一个破碎。"}
|
||||
{"role": "克莱恩", "dialogue": "“暴君”狩猎成功。"}
|
||||
{"role": "克莱恩", "dialogue": "他暂时没有成功狩猎的欣喜,只得在深渊边缘徘徊的紧绷。"}
|
||||
{"role": "克莱恩", "dialogue": "这个过程中,克莱恩让“赢家”恩佐和“地狱上将”路德维尔靠拢了自己,并将“海神权杖”丢给前者拿着,以便自己能摆脱暴躁冲动的状态,更加冷静地思考怎么应对接下来可能发生的变化,以及刚才有无其他细节被遗漏。"}
|
||||
{"role": "克莱恩", "dialogue": "他让神奇物品唱歌时,『蠕动的饥饿』有在赞美『真实造物主』,并且诵念出了完整的尊名。"}
|
||||
{"role": "克莱恩", "dialogue": "虽然那人皮手套用的不是古赫密斯语等能撬动自然力量的语言,而是赫密斯语,但后者同样能在祭祀领域发挥作用!这也就意味着,『真实造物主』很可能听到了『蠕动的饥饿』的赞美,注意到了这边发生的动静。"}
|
||||
{"role": "克莱恩", "dialogue": "除了正要上涨的『灰白洪水』和城市深处的恐怖生物,还有别的危险……等等,我现在是灵体,略等于怨魂,不是正常状态……克莱恩脑海内刚转过一个想法,灵感突有触动,本能就将目光投向了卡尔德隆的入口处。"}
|
||||
{"role": "克莱恩", "dialogue": "那里光影一闪,进来了一道身影。"}
|
||||
{"role": "克莱恩", "dialogue": "那身影套着简单而朴素的亚麻长袍,留着一头银色的长发。"}
|
||||
{"role": "克莱恩", "dialogue": "他是位男性,五官柔和,面容秀美,眼神温柔里带着些许淡漠,仿佛在以旁观者的姿态注视着命运,注视着世界上每一个人。"}
|
||||
{"role": "克莱恩", "dialogue": "……"}
|
||||
{"role": "克莱恩", "dialogue": "乌洛琉斯!"}
|
||||
{"role": "克莱恩", "dialogue": "吞尾者!"}
|
||||
{"role": "克莱恩", "dialogue": "命运天使!"}
|
||||
{"role": "克莱恩", "dialogue": "天使之王!"}
|
||||
{"role": "克莱恩", "dialogue": "这应该就是灵界掠夺者的真实魂体了……相应的粉尘也有了,大概70克,比需要的多,也比我预想的多……"}
|
||||
{"role": "克莱恩", "dialogue": "完成了这些事情,他抬手揉了揉额角,无声自嘲道:"}
|
||||
{"role": "戴莉.西蒙妮", "dialogue": "是的。"}
|
||||
{"role": "戴莉.西蒙妮", "dialogue": "帕伦克.塔西布去了哪里?"}
|
||||
{"role": "那位灵教团成员", "dialogue": "他说,他去见一个人。"}
|
||||
{"role": "戴莉.西蒙妮", "dialogue": "那个人是谁?"}
|
||||
{"role": "被通灵的男子", "dialogue": "因斯.赞格威尔。"}
|
||||
90
AITrain/utils.py
Normal file
90
AITrain/utils.py
Normal file
@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
@File : utils.py
|
||||
@Time : 2024/06/16 08:05:08
|
||||
@Author : 不要葱姜蒜
|
||||
@Version : 1.0
|
||||
@Desc : None
|
||||
'''
|
||||
|
||||
import os
|
||||
from typing import Dict, List, Optional, Tuple, Union
|
||||
|
||||
from tqdm import tqdm
|
||||
import tiktoken
|
||||
import re
|
||||
|
||||
enc = tiktoken.get_encoding("cl100k_base")
|
||||
|
||||
class ReadFiles:
|
||||
"""
|
||||
class to read files
|
||||
"""
|
||||
|
||||
def __init__(self, path: str) -> None:
|
||||
self._path = path
|
||||
|
||||
def get_content(self, max_token_len: int = 300, cover_content: int = 50):
|
||||
# 读取文件内容
|
||||
content = self.read_file_content(self._path)
|
||||
chunk_content = self.get_chunk(
|
||||
content, max_token_len=max_token_len, cover_content=cover_content)
|
||||
return chunk_content
|
||||
|
||||
@classmethod
|
||||
def get_chunk(cls, text: str, max_token_len: int = 600, cover_content: int = 150):
|
||||
chunk_text = []
|
||||
|
||||
curr_len = 0
|
||||
curr_chunk = ''
|
||||
|
||||
token_len = max_token_len - cover_content
|
||||
lines = text.splitlines() # 假设以换行符分割文本为行
|
||||
|
||||
for line in lines:
|
||||
line = line.replace(' ', '')
|
||||
line_len = len(enc.encode(line))
|
||||
if line_len > max_token_len:
|
||||
# 如果单行长度就超过限制,则将其分割成多个块
|
||||
num_chunks = (line_len + token_len - 1) // token_len
|
||||
for i in range(num_chunks):
|
||||
start = i * token_len
|
||||
end = start + token_len
|
||||
# 避免跨单词分割
|
||||
while not line[start:end].rstrip().isspace():
|
||||
start += 1
|
||||
end += 1
|
||||
if start >= line_len:
|
||||
break
|
||||
curr_chunk = (curr_chunk[-cover_content:] if cover_content > 0 else '') + line[start:end]
|
||||
chunk_text.append(curr_chunk)
|
||||
|
||||
if curr_len + line_len <= token_len:
|
||||
curr_chunk += line
|
||||
curr_chunk += '\n'
|
||||
curr_len += line_len
|
||||
curr_len += 1
|
||||
else:
|
||||
chunk_text.append(curr_chunk)
|
||||
curr_chunk = curr_chunk[-cover_content:] + line if cover_content > 0 else line
|
||||
curr_len = line_len + (cover_content if cover_content > 0 else 0)
|
||||
|
||||
if curr_chunk:
|
||||
chunk_text.append(curr_chunk)
|
||||
|
||||
return chunk_text
|
||||
|
||||
@classmethod
|
||||
def read_file_content(cls, file_path: str):
|
||||
# 根据文件扩展名选择读取方法
|
||||
if file_path.endswith('.txt'):
|
||||
return cls.read_text(file_path)
|
||||
else:
|
||||
raise ValueError("Unsupported file type")
|
||||
|
||||
@classmethod
|
||||
def read_text(cls, file_path: str):
|
||||
# 读取文本文件
|
||||
with open(file_path, 'r', encoding='utf-8') as file:
|
||||
return file.read()
|
||||
53
AITrain/vllm_model.py
Normal file
53
AITrain/vllm_model.py
Normal file
@ -0,0 +1,53 @@
|
||||
import os
|
||||
from vllm import LLM
|
||||
from vllm import SamplingParams
|
||||
from transformers import AutoTokenizer
|
||||
|
||||
os.environ['VLLM_USE_MODELSCOPE'] = 'True'
|
||||
|
||||
|
||||
def get_completion(prompts, model, tokenizer=None, temperature = 1.0, top_p = 0.95, top_k=20, min_p=0,
|
||||
max_tokens = 2048, max_model_len = 4096):
|
||||
stop_token_ids = [151645, 151643]
|
||||
# 创建采样参数。temperature 控制生成文本的多样性,
|
||||
# top_p 控制核心采样的概率,
|
||||
# top_k 通过限制候选词的数量来控制生成文本的质量和多样性,
|
||||
# min_p 通过设置概率阈值来筛选候选词,从而在保证文本质量的同时增加多样性
|
||||
sampling_params = SamplingParams(temperature=temperature, top_p=top_p,
|
||||
top_k=top_k, min_p=min_p, max_tokens=max_tokens, stop_token_ids=stop_token_ids)
|
||||
#初始化vllm推理引擎
|
||||
llm = LLM(
|
||||
model=model,
|
||||
tokenizer=tokenizer,
|
||||
max_model_len=max_model_len,
|
||||
gpu_memory_utilization=0.85,
|
||||
trust_remote_code=True,
|
||||
enforce_eager=True,
|
||||
swap_space=2 # 使用2GB交换空间
|
||||
)
|
||||
outputs = llm.generate(prompts, sampling_params)
|
||||
return outputs
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
model = '/home/tong/AIProject/Qwen/Qwen/Qwen3-0.6B'
|
||||
tokenizer = AutoTokenizer.from_pretrained(model, use_fast=False) #加载分词器
|
||||
prompt = "给我一个关于大模型的简短介绍"
|
||||
messages = [
|
||||
{"role": "user", "content": prompt}
|
||||
]
|
||||
text = tokenizer.apply_chat_template(
|
||||
messages,
|
||||
tokenize=False,
|
||||
add_generation_prompt=True,
|
||||
enable_thinking=False)
|
||||
|
||||
outputs = get_completion(text, model, tokenizer=None, temperature=0.6, top_p = 0.95, top_k=20, min_p=0) # 对于思考模式,官方建议使用以下参数:temperature = 0.6,TopP = 0.95,TopK = 20,MinP = 0。
|
||||
|
||||
# 输出是一个包含 prompt、生成文本和其他信息的 RequestOutput 对象列表。
|
||||
# 打印输出。
|
||||
for output in outputs:
|
||||
prompt = output.prompt
|
||||
generated_text = output.outputs[0].text
|
||||
print(f"Prompt: {prompt!r}, \nResponse: {generated_text!r}")
|
||||
16
AITrain/配置.txt
Normal file
16
AITrain/配置.txt
Normal file
@ -0,0 +1,16 @@
|
||||
1.安装wsl
|
||||
|
||||
2.wsl中安装conda
|
||||
|
||||
3.conda创建虚拟环境
|
||||
conda create -n AITrain python=3.12 -y
|
||||
conda activate AITrain
|
||||
conda install -c "nvidia/label/cuda-12.1.1" cuda -y
|
||||
conda install pytorch==2.3.0 torchvision==0.18.0 torchaudio==2.3.0 pytorch-cuda=12.1 -c pytorch -c nvidia -y
|
||||
|
||||
4.pip install requirements.txt -r
|
||||
|
||||
5.下载deepseek模型
|
||||
pip install modelscope
|
||||
pip install vllm
|
||||
python model_download.py
|
||||
Loading…
x
Reference in New Issue
Block a user