Qwen1.5 是 Qwen2 的测试版,Qwen2 是一种基于 Transformer 的纯解码器语言模型,在大量数据上进行了预训练。与之前发布的 Qwen 相比,改进包括:
- 6 model sizes, including 0.5B, 1.8B, 4B, 7B, 14B, and 72B;
6 种型号尺寸,包括 0.5B、1.8B、4B、7B、14B 和 72B; - Significant performance improvement in human preference for chat models;
人类对聊天模型的偏好显著提高; - Multilingual support of both base and chat models;
对基本模型和聊天模型的多语言支持; - Stable support of 32K context length for models of all sizes
稳定支持 32K 上下文长度,适用于各种尺寸的模型 - No need of
trust_remote_code
.
不需要trust_remote_code
.
1. 咱们先从最小的模型 0.5B 开始
先看看模型参数
1 2 3 4 5 6 |
from transformers import AutoModelForCausalLM, AutoTokenizer device = "cuda" model = AutoModelForCausalLM.from_pretrained(MODEL_NAME).to(device) print(model) |
运行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
Qwen2ForCausalLM( (model): Qwen2Model( (embed_tokens): Embedding(151936, 1024) (layers): ModuleList( (0-23): 24 x Qwen2DecoderLayer( (self_attn): Qwen2SdpaAttention( (q_proj): Linear(in_features=1024, out_features=1024, bias=True) (k_proj): Linear(in_features=1024, out_features=1024, bias=True) (v_proj): Linear(in_features=1024, out_features=1024, bias=True) (o_proj): Linear(in_features=1024, out_features=1024, bias=False) (rotary_emb): Qwen2RotaryEmbedding() ) (mlp): Qwen2MLP( (gate_proj): Linear(in_features=1024, out_features=2816, bias=False) (up_proj): Linear(in_features=1024, out_features=2816, bias=False) (down_proj): Linear(in_features=2816, out_features=1024, bias=False) (act_fn): SiLU() ) (input_layernorm): Qwen2RMSNorm() (post_attention_layernorm): Qwen2RMSNorm() ) ) (norm): Qwen2RMSNorm() ) (lm_head): Linear(in_features=1024, out_features=151936, bias=False) ) |
- model.embed_tokens
- model.norm
- lm_head
- model.layers (总共24层)
我们可以将Transformer模型的每一层分配给一个GPU,每个GPU可能是多层
1.1. 多 GPU 模式加载这个小模型 0.5B
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
from transformers import AutoModelForCausalLM, AutoTokenizer import torch MODEL_NAME = "Qwen/Qwen1.5-0.5B-Chat" # 定义一个函数来自动配置在多GPU环境下模型各部分的设备分布 def auto_configure_device_map(num_gpus: int): num_trans_layers = 24 # 定义Transformer模型的层数 per_gpu_layers = num_trans_layers / num_gpus # 计算每个GPU应承担的层数 # 初始化设备映射字典,指定一些特定模块应该放置的GPU编号 device_map = { 'model.embed_tokens': 0, # 嵌入层放在第一个GPU上 'model.norm': num_gpus-1, # 最后一个正则化层放在最后一个GPU上 'lm_head': 0 # 语言模型头(用于预测下一个词的层)放在最后一个GPU上 } # 将Transformer模型的每一层分配给一个GPU for i in range(num_trans_layers): device_map[f'model.layers.{i}'] = int(i//per_gpu_layers) return device_map # 检测可用的GPU数量 NUM_GPUS = torch.cuda.device_count() print(f"NUM_GPUS: {NUM_GPUS}") # 如果有可用的GPU,则基于GPU数量自动配置设备映射;否则不使用设备映射 device_map = auto_configure_device_map(NUM_GPUS) if NUM_GPUS > 0 else None # 如果有可用的GPU,则使用第一个GPU;否则使用CPU device = torch.device("cuda") if NUM_GPUS > 0 else torch.device("cpu") # 根据是否使用GPU设置数据类型(半精度或全精度) device_dtype = torch.float16 if NUM_GPUS > 0 else torch.float model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, trust_remote_code=True, torch_dtype=device_dtype, attn_implementation="flash_attention_2", device_map=device_map) # 加载分词器和模型,指定设备映射和数据类型 tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True) model = model.eval() prompt = "Give me a short introduction to large language model." messages = [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": prompt} ] text = tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True ) model_inputs = tokenizer([text], return_tensors="pt").to(device) generated_ids = model.generate( model_inputs.input_ids, max_new_tokens=512 ) generated_ids = [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) ] response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] print(response) |
运行结果:
1 2 3 4 5 6 7 8 9 10 11 12 |
python test02.py NUM_GPUS: 8 Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. A large language model is a type of artificial intelligence that can generate text based on the input given to it, without being explicitly programmed. It is commonly used in natural language processing (NLP) tasks such as language translation, chatbots, and language understanding. Large language models use a variety of techniques to learn from and generate text, including neural networks, transformers, and recurrent neural networks (RNNs). These models are trained on large datasets of labeled text data, which allows them to recognize patterns and structures within the language and generate new text that is similar to the training data. One of the key benefits of large language models is their ability to generate high-quality output quickly and consistently. They can be trained to understand the context and meaning behind the text, which makes them useful for applications where accuracy is critical. However, large language models also have some limitations. For example, they may struggle with complex or ambiguous sentences, and they may not always accurately capture the nuances of human language. Additionally, there is often a trade-off between the quality and speed of generated text, which can be challenging to balance when using large language models in real-world scenarios. Overall, large language models have had significant implications for fields such as natural language processing, machine learning, and computer vision, and continue to evolve and improve in terms of performance and adaptability. |
1.2. 试试长文章 0.5B
Qwen 1.5 来自官方的描述,说稳定支持 32K 上下文长度,适用于各种尺寸的模型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
from transformers import AutoModelForCausalLM, AutoTokenizer import torch MODEL_NAME = "Qwen/Qwen1.5-0.5B-Chat" # 定义一个函数来自动配置在多GPU环境下模型各部分的设备分布 def auto_configure_device_map(num_gpus: int): num_trans_layers = 24 # 定义Transformer模型的层数 per_gpu_layers = num_trans_layers / num_gpus # 计算每个GPU应承担的层数 # 初始化设备映射字典,指定一些特定模块应该放置的GPU编号 device_map = { 'model.embed_tokens': 0, # 嵌入层放在第一个GPU上 'model.norm': num_gpus-1, # 最后一个正则化层放在最后一个GPU上 'lm_head': 0 # 语言模型头(用于预测下一个词的层)放在最后一个GPU上 } # 将Transformer模型的每一层分配给一个GPU for i in range(num_trans_layers): device_map[f'model.layers.{i}'] = int(i//per_gpu_layers) return device_map # 检测可用的GPU数量 NUM_GPUS = torch.cuda.device_count() print(f"NUM_GPUS: {NUM_GPUS}") # 如果有可用的GPU,则基于GPU数量自动配置设备映射;否则不使用设备映射 device_map = auto_configure_device_map(NUM_GPUS) if NUM_GPUS > 0 else None # 如果有可用的GPU,则使用第一个GPU;否则使用CPU device = torch.device("cuda") if NUM_GPUS > 0 else torch.device("cpu") # 根据是否使用GPU设置数据类型(半精度或全精度) device_dtype = torch.float16 if NUM_GPUS > 0 else torch.float model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, trust_remote_code=True, torch_dtype=device_dtype, attn_implementation="flash_attention_2", device_map=device_map) # 加载分词器和模型,指定设备映射和数据类型 tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True) model = model.eval() prompt = "写一个3万字的有头有尾的短篇科幻小说." messages = [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": prompt} ] text = tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True ) model_inputs = tokenizer([text], return_tensors="pt").to(device) generated_ids = model.generate( model_inputs.input_ids, max_new_tokens=32000 ) generated_ids = [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) ] response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] print(response) |
运行结果如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
time python test03.py NUM_GPUS: 8 Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. 标题:《未来之光》 在未来的2078年,地球表面已经被一颗名为“星际火球”的未知星球完全覆盖。这颗星球上充满了奇异的现象,包括无限的生命体、时间旅行等。 主角是地球上的科学家艾伦,他决定带着他的团队去探索这个全新的世界。他们在星际火球上发现了一种新型的能源,这种能源是一种可以被人类无限次利用的物质,被称为“光子”。 然而,光子并非一帆风顺。他们首先遇到了一种无法克服的物理挑战——光子具有极高的能量密度,一旦进入人类的皮肤,就会瞬间燃烧。他们的研究方向是从如何将光子转化为能量进行使用开始。 艾伦和他的团队开始了漫长的实验,最终他们成功地制造出了这种新的能源。但是,光子的出现也带来了一些问题。他们需要找到一种方法来保护这种能源不被污染,同时也不能过度开发和利用。 在这个过程中,他们与一些外星文明进行了交流,他们向艾伦提供了先进的能源生产技术,并提出了对他们的保护方案。艾伦接受了这些提议,于是他们开始了一场对抗外星文明的战斗。 在激烈的战斗中,他们的团队遭受了重创,但他们并未放弃。他们通过智慧和勇气,成功地击败了外星文明,保护了他们的家园。 在战斗结束后,艾伦回到了地球上,他感谢所有的帮助,也感谢他的朋友们。他告诉人们,虽然科技的发展带来了很多便利,但也需要我们珍惜我们的资源,保护好我们的环境。 这就是《未来之光》,一个充满挑战又充满希望的故事。它告诉我们,只要我们敢于面对困难,勇于创新,就一定能够创造出属于自己的未来。 real 1m4.372s user 0m38.394s sys 0m8.390s |
1.3 试试 0.5B 单GPU加载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
from transformers import AutoModelForCausalLM, AutoTokenizer import torch MODEL_NAME = "Qwen/Qwen1.5-0.5B-Chat" # 检测可用的GPU数量 NUM_GPUS = torch.cuda.device_count() print(f"NUM_GPUS: {NUM_GPUS}") # 如果有可用的GPU,则使用第一个GPU;否则使用CPU device = torch.device("cuda") if NUM_GPUS > 0 else torch.device("cpu") # 根据是否使用GPU设置数据类型(半精度或全精度) device_dtype = torch.float16 if NUM_GPUS > 0 else torch.float model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, trust_remote_code=True, torch_dtype=device_dtype, attn_implementation="flash_attention_2", device_map="cuda:0") # 加载分词器和模型,指定设备映射和数据类型 tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True) model = model.eval() prompt = "写一个1万字的有头有尾的短篇科幻小说." messages = [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": prompt} ] text = tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True ) model_inputs = tokenizer([text], return_tensors="pt").to(device) generated_ids = model.generate( model_inputs.input_ids, max_new_tokens=10000 ) generated_ids = [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) ] response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] print(response) |
运行结果:
time python test05-0.5B-2.py
NUM_GPUS: 8
Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained.
标题:星际危机
故事的主角是地球上的科学家,亚历山大。他被选为了创建一艘新的火星船,并开始了他的旅程。他的飞船名为“瑞尔德”,由先进的人造能源系统和先进的通讯设备组成。
一天,亚历山大在研究行星表面时发现了一个异常的现象,他的船突然失去了动力。他立刻启动了应急程序,用他的所有技术来修复这个故障。然而,当他在检查船上时,发现了一颗星球的表面覆盖着一层神秘的物质。这些物质似乎是一种能够吸收和转换能量的能源。亚历山大无法理解这是什么,他决定使用他的科学知识去寻找答案。
在接下来的几个月里,亚历山大和他的团队一起研究了这种物质的存在方式,他们发现这颗星球的表面有着一种奇特的能量释放器。这种能量释放器可以将星球的能量转化为光,然后以热能的形式传输到其他星球。亚历山大决定利用这个能源释放器,把所有的能量都集中在一次燃料释放上,希望这次能源释放能让他们的飞船恢复正常运行。
然而,在释放能量的过程中,飞船发生了严重的问题。它开始向太空喷射大量的燃料,但是燃料的燃烧没有完全熄灭。最后,亚历山大和他的团队被迫撤回了他们的飞船。他们的损失惨重,但他们的勇气和决心却使他们坚持了下来。
他们的任务不仅拯救了他们的飞船,也拯救了他们自己。亚历山大成为了人类历史上第一位成功地通过航天飞行改变世界的人物。他让人们明白,只要有坚定的决心和不懈的努力,就一定能够克服任何困难,实现自己的梦想。
尽管他们的冒险充满了挑战和风险,但他们仍然坚信,只要他们相信自己,就可以克服任何困难,实现自己的梦想。他们的故事激励着人们,让人们知道,只要有勇气和智慧,就能够改变世界。
real 1m43.555s
user 0m32.418s
sys 0m10.565s
2. 1.8B 模型,多GPU
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
from transformers import AutoModelForCausalLM, AutoTokenizer import torch import time MODEL_NAME = "Qwen/Qwen1.5-1.8B-Chat" # 定义一个函数来自动配置在多GPU环境下模型各部分的设备分布 def auto_configure_device_map(num_gpus: int): num_trans_layers = 24 # 定义Transformer模型的层数 per_gpu_layers = num_trans_layers / num_gpus # 计算每个GPU应承担的层数 # 初始化设备映射字典,指定一些特定模块应该放置的GPU编号 device_map = { 'model.embed_tokens': 0, # 嵌入层放在第一个GPU上 'model.norm': num_gpus-1, # 最后一个正则化层放在最后一个GPU上 'lm_head': 0 # 语言模型头(用于预测下一个词的层)放在最后一个GPU上 } # 将Transformer模型的每一层分配给一个GPU for i in range(num_trans_layers): device_map[f'model.layers.{i}'] = int(i//per_gpu_layers) return device_map # 检测可用的GPU数量 NUM_GPUS = torch.cuda.device_count() print(f"NUM_GPUS: {NUM_GPUS}") # 如果有可用的GPU,则基于GPU数量自动配置设备映射;否则不使用设备映射 device_map = auto_configure_device_map(NUM_GPUS) if NUM_GPUS > 0 else None # 如果有可用的GPU,则使用第一个GPU;否则使用CPU device = torch.device("cuda") if NUM_GPUS > 0 else torch.device("cpu") # 根据是否使用GPU设置数据类型(半精度或全精度) device_dtype = torch.float16 if NUM_GPUS > 0 else torch.float # 获取起始时间戳 start_time = time.time() model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, trust_remote_code=True, torch_dtype=device_dtype, attn_implementation="flash_attention_2", device_map=device_map) # 加载分词器和模型,指定设备映射和数据类型 tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True) model = model.eval() end_time = time.time() elapsed_time = end_time - start_time print(f"Load Model Time: {elapsed_time} seconds") start_time2 = time.time() prompt = "写一个2万字的有头有尾的短篇科幻小说." messages = [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": prompt} ] text = tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True ) model_inputs = tokenizer([text], return_tensors="pt").to(device) generated_ids = model.generate( model_inputs.input_ids, max_new_tokens=20000 ) generated_ids = [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) ] response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] end_time2 = time.time() elapsed_time2 = end_time2 - start_time2 elapsed_time = end_time2 - start_time print(response) # 计算每秒处理的token数量 num_tokens_generated = generated_ids.shape[1] # 生成的token总数 tokens_per_second = num_tokens_generated / elapsed_time2 print(f"Tokens per second: {tokens_per_second}") print(f"Total Time: {elapsed_time} seconds") |
结果运行如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
time python test05-1.8B.py NUM_GPUS: 8 Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. Load Model Time: 63.05974817276001 seconds 标题:穿越时空的战士 在一个遥远的未来,人类社会已经发展到星际殖民的程度。在这个时代中,科技高度发达,人工智能、量子计算机和新能源技术的应用已超越了人类想象。然而,尽管人们生活在一个繁荣昌盛的世界里,但也面临着许多未知的挑战和危机。 在一次国际性的星际竞赛中,一支由科学家和工程师组成的精英团队赢得了比赛,他们成功地将一颗古老的星际石带到了人类的星球——地球。这颗星际石被称为“时间之碑”,据说它拥有无限的时间旅行能力,能够让探险者回到过去或未来的任何一个时刻。 随着星际石的到来,一系列惊人的事件接踵而至。科学家们利用石碑的力量探索并研究地球的历史与未来,发现了一些以前未被人类知晓的秘密。同时,石碑也引发了一场大规模的人类觉醒运动,人们开始质疑过去的错误决策和对未来未来的恐惧。越来越多的人选择离开家乡,踏上寻找答案和改变命运的旅程。 其中,一位名叫艾米丽的女性成为了这场变革的主要推动者。她是一位有着超凡智慧和坚韧意志的年轻科学家,也是石碑使用者之一。在石碑的帮助下,艾米丽解开了许多复杂的科学谜团,甚至在面对一些看似不可能解决的问题时,她凭借自己的勇气和决心找到了解决方案。 在经历了一系列生死考验后,艾米丽最终发现了人类社会的本质问题所在:我们的行为模式正在破坏我们自身和后代的生活质量。为了改变这个状况,艾米丽决定返回过去,阻止那些导致人类灭亡的行为。她的目标是唤醒人们对过去的反思,让人们意识到错误的决策,并采取行动来纠正它们。 艾米丽带着石碑回到了过去,但这次她不再是普通的科学家。她的身份被赋予了一项全新的使命——时间守护者。她不仅要保护时间碑不被滥用,还要通过自己的行动引导历史走向更美好的未来。在这个过程中,她遇到了各种各样的人,包括曾经被她拯救的幸存者、被历史遗忘的英雄和对艾米丽怀有敌意的人。 经过无数次的战斗和挫折,艾米丽逐渐成为了一个真正的领袖。她用自己的知识和勇气赢得了人们的信任和支持,带领着时间守护者的队伍走向了新的征途。他们的故事激励着每一个试图找到自我价值和改变世界的人,他们在追求真理的路上,共同创造了一个更加公正、和平、可持续的未来。 《穿越时空的战士》以艾米丽为代表的一群人的冒险旅程为线索,描绘了一个充满挑战和希望的未来世界。它通过深入探讨人类文明发展的历程,揭示出我们对过去和未来的认知局限,以及如何通过勇敢面对困难,实现自我成长和历史进步。这部作品既是一部科幻小说,又是一部关于人性、勇气和责任的故事,寓意深远,引人深思。 Generated Tokens: 584 Tokens per second: 6.205085219425609 Total Generation Time: 94.11635446548462 seconds real 2m41.035s user 1m48.874s sys 0m20.042s |
2.2 1.8B 模型,单GPU
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
from transformers import AutoModelForCausalLM, AutoTokenizer import torch import time MODEL_NAME = "Qwen/Qwen1.5-1.8B-Chat" # 检测可用的GPU数量 NUM_GPUS = torch.cuda.device_count() print(f"NUM_GPUS: {NUM_GPUS}") # 如果有可用的GPU,则使用第一个GPU;否则使用CPU device = torch.device("cuda") if NUM_GPUS > 0 else torch.device("cpu") # 根据是否使用GPU设置数据类型(半精度或全精度) device_dtype = torch.float16 if NUM_GPUS > 0 else torch.float # 获取起始时间戳 start_time = time.time() model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, trust_remote_code=True, torch_dtype=device_dtype, attn_implementation="flash_attention_2", device_map="cuda:0") # 加载分词器和模型,指定设备映射和数据类型 tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True) model = model.eval() end_time = time.time() elapsed_time = end_time - start_time print(f"Load Model Time: {elapsed_time} seconds") start_time2 = time.time() prompt = "写一个2万字的有头有尾的短篇科幻小说." messages = [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": prompt} ] text = tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True ) model_inputs = tokenizer([text], return_tensors="pt").to(device) generated_ids = model.generate( model_inputs.input_ids, max_new_tokens=20000 ) end_time2 = time.time() elapsed_time2 = end_time2 - start_time2 elapsed_time = end_time2 - start_time num_tokens_generated = len(generated_ids[0]) - len(model_inputs.input_ids[0]) tokens_per_second = num_tokens_generated / elapsed_time2 generated_ids = [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) ] response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] print(response) print(f"Generated Tokens: {num_tokens_generated}") print(f"Tokens per second: {tokens_per_second}") print(f"Total Generation Time: {elapsed_time2} seconds") |
运行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
time python test05-1.8B-2.py NUM_GPUS: 8 Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. Load Model Time: 67.75650358200073 seconds 标题:宇宙之门 在遥远的银河系中,有一个名为艾利斯的星系,被誉为生命和科技的摇篮。艾利斯拥有众多美丽的星球,其中一颗名叫“纳鲁”的星球以其独特的环境和丰富的资源著称。 纳鲁星球表面覆盖着一层稀薄的冰层,犹如一片晶莹剔透的海洋,反射出无尽的蓝色星光。在这个寒冷的星球上,生活着一种智慧生物——纳鲁人,他们以自然的方式生存和发展,擅长种植和采集各种食物和资源,以此来维持他们的生存需求。 纳鲁人的科技远超其他同类物种,他们使用一种神秘的能量石块,可以将任何物质转化为能源,甚至可以直接操控和操纵整个星球的生态系统。这种能量石块被他们视为生命的基石,是他们智慧和力量的象征。 然而,纳鲁星球的秘密也逐渐浮出水面。据传说,纳鲁星球曾经是一颗巨大的恒星,由于某种未知的原因,它的核心发生了爆炸,强大的冲击波将它带到了这个荒凉而陌生的行星上。随着时间的推移,纳鲁星球上的生命逐渐进化,形成了独特的纳鲁文明。 然而,随着纳鲁文明的发展,他们的生活方式开始与地球人类截然不同。他们不再依赖于大自然的恩赐,而是通过科技手段控制和利用自然资源,甚至开始对其他星球进行殖民和开发。这种行为引起了纳鲁社会内部的矛盾和冲突,一些纳鲁人选择离开他们的家园,前往更加适合他们的星球生活。 在这个过程中,纳鲁科学家发现了一种新的能量石块,它不仅可以将纳鲁星球上的物质转化为能源,还可以修复纳鲁星球的核心,并恢复其曾经的光辉。但这种新能量石块并不简单,需要极高的技术含量和复杂的能量转化过程。 科学家们决定深入研究纳鲁星球的能量石块,希望从中获取突破性的科技突破。他们在星球的地下深处,挖掘出了一个神秘的能量矿脉,那里充满了奇特的能量晶体,每一个都蕴含着全新的能量转换原理。 经过多年的探索和实验,科学家们终于成功提取出了这种能量晶体,并将其应用于纳鲁星球的能量石块上。在无数次的试验和失败后,他们终于成功地将这种能量晶体转化为能源,使得纳鲁星球的能源得到了全面的恢复。 同时,科学家们也发现了纳鲁星球的核心发生了质的变化,核心中的核心石块已经失去了先前的能量波动,显示出明显的能量流失迹象。这无疑是一个重大的危机,如果继续按照现有的发展模式,纳鲁星球将会失去核心的力量,无法抵抗外部的入侵和威胁。 于是,科学家们决定重启纳鲁星球的核心石块,试图修复其原有的能量状态。他们进行了精心的模拟实验,最终成功地使核心石块重新获得了能量波动,使其再次具有了能量驱动的功能。 经过这次重置,纳鲁星球的人类社区开始重新崛起,他们用先进的科技手段改造了自己的生活环境,成功地抵御住了来自宇宙的各种外力侵袭。与此同时,纳鲁人也开始反思自己的发展模式,认识到过度开发和利用资源可能带来的严重后果,开始了可持续发展的道路。 纳鲁星球的故事告诉我们,科技并非万能,只有当人们尊重自然,合理利用自然资源,才能实现真正的可持续发展。在未来的世界里,纳鲁人将以此为鉴,继续在科技与环保之间寻找平衡,为构建和谐、繁荣的宇宙世界做出更大的贡献。 Generated Tokens: 715 Tokens per second: 29.989652369309425 Total Generation Time: 23.841556787490845 seconds real 1m34.365s user 0m41.232s sys 0m18.896s |
3. 4B 多GPU 加载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
from transformers import AutoModelForCausalLM, AutoTokenizer import torch import time MODEL_NAME = "Qwen/Qwen1.5-4B-Chat" # 定义一个函数来自动配置在多GPU环境下模型各部分的设备分布 def auto_configure_device_map(num_gpus: int): num_trans_layers = 40 # 定义Transformer模型的层数 per_gpu_layers = num_trans_layers / num_gpus # 计算每个GPU应承担的层数 # 初始化设备映射字典,指定一些特定模块应该放置的GPU编号 device_map = { 'model.embed_tokens': 0, # 嵌入层放在第一个GPU上 'model.norm': num_gpus-1, # 最后一个正则化层放在最后一个GPU上 'lm_head': 0 # 语言模型头(用于预测下一个词的层)放在最后一个GPU上 } # 将Transformer模型的每一层分配给一个GPU for i in range(num_trans_layers): device_map[f'model.layers.{i}'] = int(i//per_gpu_layers) return device_map # 检测可用的GPU数量 NUM_GPUS = torch.cuda.device_count() print(f"NUM_GPUS: {NUM_GPUS}") # 如果有可用的GPU,则基于GPU数量自动配置设备映射;否则不使用设备映射 device_map = auto_configure_device_map(NUM_GPUS) if NUM_GPUS > 0 else None # 如果有可用的GPU,则使用第一个GPU;否则使用CPU device = torch.device("cuda") if NUM_GPUS > 0 else torch.device("cpu") # 根据是否使用GPU设置数据类型(半精度或全精度) device_dtype = torch.float16 if NUM_GPUS > 0 else torch.float # 获取起始时间戳 start_time = time.time() model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, trust_remote_code=True, torch_dtype=device_dtype, attn_implementation="flash_attention_2", device_map=device_map) # 加载分词器和模型,指定设备映射和数据类型 tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True) model = model.eval() end_time = time.time() elapsed_time = end_time - start_time print(f"Load Model Time: {elapsed_time} seconds") start_time2 = time.time() prompt = "写一个2万字的有头有尾的短篇科幻小说." messages = [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": prompt} ] text = tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True ) model_inputs = tokenizer([text], return_tensors="pt").to(device) generated_ids = model.generate( model_inputs.input_ids, max_new_tokens=20000 ) end_time2 = time.time() elapsed_time2 = end_time2 - start_time2 elapsed_time = end_time2 - start_time num_tokens_generated = len(generated_ids[0]) - len(model_inputs.input_ids[0]) tokens_per_second = num_tokens_generated / elapsed_time2 generated_ids = [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) ] response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] print(response) print(f"Generated Tokens: {num_tokens_generated}") print(f"Tokens per second: {tokens_per_second}") print(f"Total Generation Time: {elapsed_time2} seconds") |
运行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
time python test05-4B.py NUM_GPUS: 8 Loading checkpoint shards: 100%|███████████| 2/2 [03:07<00:00, 93.74s/it] Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. Load Model Time: 191.43567776679993 seconds 非常抱歉,作为一个AI文本生成模型,我无法一次性为您生成2万字的内容。但是,我可以帮助您开始写 作或者为您提供一些创意和灵感。请您告诉我更多的细节,例如故事的主题、主要角色等。这样我才能更好地为您提供帮助。 Generated Tokens: 54 Tokens per second: 2.780886061220365 Total Generation Time: 19.41827130317688 seconds real 3m35.004s user 0m56.952s sys 0m27.279s |
这么实在的么?再运行一次
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
time python test05-4B.py NUM_GPUS: 8 Loading checkpoint shards: 100%|██████████████| 2/2 [02:10<00:00, 65.05s/it] Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. Load Model Time: 134.07681465148926 seconds 标题:《星际之眼》 在遥远的未来,地球文明已经达到了前所未有的高度。科技的发展,使得人类开始对宇宙进行探索,寻找新的生命形式和可能存在的外星文明。 在这个过程中,科学家们发现了一种名为"星际之眼"的神秘物质,它能够吸收和反射光线,使得任何生物都能通过它看到更远的地方,甚至可以看到其他星球的信息。 然而,这种"星际之眼"的出现,并没有让人类欣喜若狂,反而引起了恐慌。因为科学家们发现,这种物质可能会吸引外来生命的入侵,而且如果被滥用,也有可能对地球造成严重的破坏。 于是,一场关于如何保护和利用"星际之眼"的辩论开始了。一些人主张关闭"星际之眼",防止不必要的干扰;另一些人则认为应该继续研究和开发它的潜力,以推动人类的科技进步。 在这个争论中,一位名叫杰克的年轻人站了出来。他提出,人类不应该害怕未知,而应该勇于探索和挑战。他坚信,只有通过不断的努力和探索,人类才能找到真正的自我,才能改变世界。 于是,杰克决定独自一个人去探索"星际之眼"的秘密。经过了无数个日夜的努力,杰克终于成功地揭示了"星际之眼"的秘密。原来,这种物质其实是一种可以让人看到真实世界的能量,只要正确使用,就能够让人类更好地了解和探索宇宙。 在杰克的领导下,人类成功地利用了"星际之眼"的力量,进行了大量的宇宙探索。他们发现了更多的新星球,了解到了更多生命的奥秘,甚至找到了与地球相似的生命形式。 然而,这个过程并没有结束。由于地球的能量消耗过大,"星际之眼"开始逐渐衰退。为了保护这个珍贵的资源,杰克提出了一个大胆的计划:人类需要寻找新的能源,来替代"星际之眼"的能量。 在杰克的带领下,人类开始了艰难的寻找新能源的过程。他们研发出了各种先进的科技,试图找到一种能够替代"星际之眼"的新能量。经过无数次的失败和挫折,人类终于成功地找到了新的能源。 随着新能源的投入,"星际之眼"再次恢复了活力,人类的宇宙探索又重新进入了高潮。他们不仅找到了更多的新星球,还发现了更多的生命形式,甚至发现了一些与地球相似的生命形式。 最后,杰克带领人类成功地改变了世界。他们用自己的智慧和勇气,创造了一个全新的、充满希望的世界。人类不再是孤独的个体,而是成为了宇宙的一部分,与所有生命共同构成了一个和谐的宇宙。 这就是"星际之眼"的故事,一个关于探索、挑战和希望的故事。这个故事告诉我们,只要有梦想,有勇气,就一定能够实现自己的目标。 Generated Tokens: 566 Tokens per second: 2.9105564016095413 Total Generation Time: 194.46453595161438 seconds real 5m32.603s user 3m43.533s sys 0m36.183s |
3.2. 4B 单GPU
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
from transformers import AutoModelForCausalLM, AutoTokenizer import torch import time MODEL_NAME = "Qwen/Qwen1.5-4B-Chat" # 检测可用的GPU数量 NUM_GPUS = torch.cuda.device_count() print(f"NUM_GPUS: {NUM_GPUS}") # 如果有可用的GPU,则使用第一个GPU;否则使用CPU device = torch.device("cuda") if NUM_GPUS > 0 else torch.device("cpu") # 根据是否使用GPU设置数据类型(半精度或全精度) device_dtype = torch.float16 if NUM_GPUS > 0 else torch.float # 获取起始时间戳 start_time = time.time() model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, trust_remote_code=True, torch_dtype=device_dtype, attn_implementation="flash_attention_2", device_map="cuda:0") # 加载分词器和模型,指定设备映射和数据类型 tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True) model = model.eval() end_time = time.time() elapsed_time = end_time - start_time print(f"Load Model Time: {elapsed_time} seconds") start_time2 = time.time() prompt = "写一个2万字的有头有尾的短篇科幻小说." messages = [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": prompt} ] text = tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True ) model_inputs = tokenizer([text], return_tensors="pt").to(device) generated_ids = model.generate( model_inputs.input_ids, max_new_tokens=20000 ) end_time2 = time.time() elapsed_time2 = end_time2 - start_time2 elapsed_time = end_time2 - start_time num_tokens_generated = len(generated_ids[0]) - len(model_inputs.input_ids[0]) tokens_per_second = num_tokens_generated / elapsed_time2 generated_ids = [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) ] response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] print(response) print(f"Generated Tokens: {num_tokens_generated}") print(f"Tokens per second: {tokens_per_second}") print(f"Total Generation Time: {elapsed_time2} seconds") |
运行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
time python test05-4B-2.py NUM_GPUS: 8 Loading checkpoint shards: 100%|██████████████| 2/2 [02:03<00:00, 61.86s/it] Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. Load Model Time: 127.5276780128479 seconds 对不起,由于篇幅限制,我无法为您提供一个完整的2万字的科幻小说。但我可以为您列出一个大致的情 节大纲和开头部分: 标题:星尘中的救赎 一、开头 在一颗遥远的星球上,科学家们发现了一种能够实现星际旅行的新技术——"光子引擎"。 二、情节发展 科学家们利用光子引擎探索宇宙,寻找可能存在的外星生命。然而,在一次冒险中,他们意外撞入了一个未知的黑洞。 三、转折点 当他们的飞船在黑洞边缘出现时,他们被吸入了黑洞,成为了一群被困在这个宇宙黑暗世界中的幸存者。 四、高潮 他们试图找到逃脱黑洞的方法,但是这个过程充满了困难和挑战。在这期间,他们发现了许多关于这个黑洞的秘密,甚至可能揭示出一个更大的宇宙秘密。 五、结局 在经历了无数的挫折和困难后,他们最终找到了逃脱黑洞的方法,并成功地回到了自己的星球。虽然他们失去了许多宝贵的时间,但他们也从这次经历中学到了许多宝贵的知识和经验。 这是一个大概的情节梗概,您可以根据这个梗概开始编写您的小说。我希望这能对您有所帮助! Generated Tokens: 248 Tokens per second: 23.96475511752906 Total Generation Time: 10.348530530929565 seconds real 2m20.750s user 0m42.449s sys 0m32.544s |
4. 7B的模型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
from transformers import AutoModelForCausalLM, AutoTokenizer import torch MODEL_NAME = "Qwen/Qwen1.5-7B-Chat" # 定义一个函数来自动配置在多GPU环境下模型各部分的设备分布 def auto_configure_device_map(num_gpus: int): num_trans_layers = 32 # 定义Transformer模型的层数 per_gpu_layers = num_trans_layers / num_gpus # 计算每个GPU应承担的层数 # 初始化设备映射字典,指定一些特定模块应该放置的GPU编号 device_map = { 'model.embed_tokens': 0, # 嵌入层放在第一个GPU上 'model.norm': num_gpus-1, # 最后一个正则化层放在最后一个GPU上 'lm_head': 0 # 语言模型头(用于预测下一个词的层)放在最后一个GPU上 } # 将Transformer模型的每一层分配给一个GPU for i in range(num_trans_layers): device_map[f'model.layers.{i}'] = int(i//per_gpu_layers) return device_map # 检测可用的GPU数量 NUM_GPUS = torch.cuda.device_count() print(f"NUM_GPUS: {NUM_GPUS}") # 如果有可用的GPU,则基于GPU数量自动配置设备映射;否则不使用设备映射 device_map = auto_configure_device_map(NUM_GPUS) if NUM_GPUS > 0 else None # 如果有可用的GPU,则使用第一个GPU;否则使用CPU device = torch.device("cuda") if NUM_GPUS > 0 else torch.device("cpu") # 根据是否使用GPU设置数据类型(半精度或全精度) device_dtype = torch.float16 if NUM_GPUS > 0 else torch.float model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, trust_remote_code=True, torch_dtype=device_dtype, attn_implementation="flash_attention_2", device_map=device_map) # 加载分词器和模型,指定设备映射和数据类型 tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True) model = model.eval() prompt = "写一个2万字的有头有尾的短篇科幻小说." messages = [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": prompt} ] text = tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True ) model_inputs = tokenizer([text], return_tensors="pt").to(device) generated_ids = model.generate( model_inputs.input_ids, max_new_tokens=20000 ) generated_ids = [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) ] response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] print(response) |
运行结果如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
time python test05-7B.py NUM_GPUS: 8 Loading checkpoint shards: 100%|█████████████████████| 4/4 [04:33<00:00, 68.44s/it] Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. 标题:星际尘埃的回响 在遥远的未来,地球已经步入了科技高度发达的新纪元。人类不再局限于蓝色星球,他们开拓了宇宙,建立了星际联盟,探索未知,寻找新的生存空间。在这个宏大的背景下,我们的故事就在一颗名为“赛博利亚”的殖民星球展开。 故事的主角,艾登·哈特,是一位年轻的星际探险家,他出生并成长于地球,但对那颗蓝色星球的记忆却如同遥远的童年梦 。他的梦想是找到传说中的"时间之源"——一种可以修复和延长生命的神秘能源,以拯救因资源枯竭而濒临崩溃的地球。 赛博利亚,一颗被废弃的矿星,曾是地球资源的宝库,但现在,它满目疮痍,生态系统严重受损。艾登受命带领一支小型探索队来到这里,他们的任务是揭开这颗星球的秘密,寻找可能存在的"时间之源"。 队伍由经验丰富的老队长莉亚、技术精湛的科学家凯瑟琳、以及勇敢无畏的机械师亚当组成。他们在赛博利亚的废墟中发现了一座古老的遗迹,其上的壁画描绘了一个神秘的循环图案,似乎暗示着时间的奥秘。 随着深入研究,他们发现这个星球曾遭受过一场灾难性的时空扭曲,导致时间流速异常,生物寿命缩短。而那个"时间之源",正是修复这种失衡的关键。然而,遗迹的守护者,一只古老智慧的机械生命体,警告他们,任何试图改变时间的行为都可能导致无法预料的后果。 在紧张的抉择中,艾登决定冒险,他相信只有通过理解和尊重自然,才能找到真正的救赎。他与机械生命体进行了一场智慧的博弈,最终赢得了它的信任,并成功启动了"时间稳定器",稳定了赛博利亚的时间流速。 修复后的赛博利亚开始恢复生机,生物种类繁多,绿色重新覆盖大地。艾登和他的团队成为了英雄,他们的事迹被星际联盟广为传颂。他们带着赛博利亚的重生秘密,回到了地球,为人类的未来带来了希望。 然而,故事并未结束,艾登明白,他们的使命是永恒的,他们将继续在星辰大海中探索,寻找更多的答案,保护这个宇宙的平衡。"时间之源"的故事,就像一首未完的交响曲,回荡在无尽的宇宙中,激励着每一个勇往直前的探险者。 这就是《星际尘埃的回响》——一个关于勇气、智慧和爱的科幻短篇,讲述了人类在面对困境时的坚韧与决心,以及对未知世界的无尽探索。 real 9m42.229s user 5m38.796s sys 1m7.439s |
从上面结果来看,
总花费时间为:9:42
模型加载时间为4:33
5分钟内生成了809个汉字,每秒大约2.6个汉字,速度还可以
5. 7B 的模型 device_map 使用 auto 方式
auto 方式仍然是使用多个GPU,只是分的比较平均
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
from transformers import AutoModelForCausalLM, AutoTokenizer import torch MODEL_NAME = "Qwen/Qwen1.5-7B-Chat" # 检测可用的GPU数量 NUM_GPUS = torch.cuda.device_count() print(f"NUM_GPUS: {NUM_GPUS}") # 如果有可用的GPU,则使用第一个GPU;否则使用CPU device = torch.device("cuda") if NUM_GPUS > 0 else torch.device("cpu") # 根据是否使用GPU设置数据类型(半精度或全精度) device_dtype = torch.float16 if NUM_GPUS > 0 else torch.float model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, trust_remote_code=True, torch_dtype=device_dtype, attn_implementation="flash_attention_2", device_map="auto") # 加载分词器和模型,指定设备映射和数据类型 tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True) model = model.eval() prompt = "写一个2万字的有头有尾的短篇科幻小说." messages = [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": prompt} ] text = tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True ) model_inputs = tokenizer([text], return_tensors="pt").to(device) generated_ids = model.generate( model_inputs.input_ids, max_new_tokens=20000 ) generated_ids = [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) ] response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] print(response) |
运行结果如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
time python test05-7B-2.py NUM_GPUS: 8 Loading checkpoint shards: 100%|████████████| 4/4 [03:50<00:00, 57.51s/it] Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. 标题:星际迷航:未知的脉动 在遥远的未来,人类已经掌握了星际旅行,探索宇宙成为了日常生活的一部分。故事发生在一个名为"诺 兰星云"的神秘星系,这里隐藏着一个被遗忘的秘密。 主角,艾登·柯林斯,是一位年轻的星际探险家,他的父亲曾是著名的宇航员,因一次神秘任务失踪,留 下了一本尘封的日 记,里面记载了关于“脉动星球”的线索。这个星球据说拥有超越科技的能量源,吸引 了全球科学家的目光,却因其极端环境而无人能触及。 艾登决定挑战自我,带领一支由各领域精英组成的科研团队,踏上了寻找“脉动星球”的旅程。他们的飞船——“曙光号”,在浩渺的星海中穿行,遭遇了未知的黑洞、外星生物和恶劣的气候,但他们始终保持信念,勇往直前。 在一次意外中,他们发现了一个看似荒芜的星球——泰坦。这里的环境比想象中更为恶劣,但艾登发现星球表面的奇特纹理与父亲日记中的描述惊人相似。他坚信这就是“脉动星球”。 团队成员们开始深入研究,他们发现泰坦的土壤蕴含着一种前所未见的元素,这种元素释放出微弱但稳定的波动,似乎就是传说中的能量源。然而,这种波动也引来了一种名为“暗影生物”的威胁,它们对这种波动异常敏感,企图吞噬一切。 艾登决定冒险进入泰坦的核心地带,希望能找到控制波动的关键。他与团队成员并肩作战,面对生死考验。在生死边缘,他们发现了暗影生物的弱点,原来它们惧怕光,而泰坦核心深处正是最强烈的光源。 经过一场惊心动魄的决战,艾登成功激活了核心的能量,波动逐渐稳定下来。他带着宝贵的样本返回地球,人类社会因此迎来了新的科技革命,疾病、能源问题得到了前所未有的解决。 然而,艾登并未停下脚步,他继续探索宇宙,寻找更多未知的奥秘。他的故事激励着一代又一代的星际探险者,他们将父亲的勇气和智慧传承下去,继续在无尽的星海中寻找生命的起源和宇宙的真谛。 《星际迷航:未知的脉动》以艾登的冒险为线索,讲述了科技、友情和牺牲的力量,描绘了一个充满希望与挑战的未来世界。 real 8m51.094s user 5m25.063s sys 1m7.385s |
从上面结果来看,
总花费时间为:8:51
模型加载时间为3:50
5分钟内生成了840个汉字,每秒大约2.8个汉字,速度比前面快一点
6. 7B 的模型 只使用一个 GPU
7B 的模型只要14G左右,所以使用一个24G的 RTX 4090 是可以装载的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
from transformers import AutoModelForCausalLM, AutoTokenizer import torch MODEL_NAME = "Qwen/Qwen1.5-7B-Chat" # 检测可用的GPU数量 NUM_GPUS = torch.cuda.device_count() print(f"NUM_GPUS: {NUM_GPUS}") # 如果有可用的GPU,则使用第一个GPU;否则使用CPU device = torch.device("cuda") if NUM_GPUS > 0 else torch.device("cpu") # 根据是否使用GPU设置数据类型(半精度或全精度) device_dtype = torch.float16 if NUM_GPUS > 0 else torch.float model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, trust_remote_code=True, torch_dtype=device_dtype, attn_implementation="flash_attention_2", device_map="cuda:0") # 加载分词器和模型,指定设备映射和数据类型 tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True) model = model.eval() prompt = "写一个2万字的有头有尾的短篇科幻小说." messages = [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": prompt} ] text = tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True ) model_inputs = tokenizer([text], return_tensors="pt").to(device) generated_ids = model.generate( model_inputs.input_ids, max_new_tokens=20000 ) generated_ids = [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) ] response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] print(response) |
运行结果如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
time python test05-7B-3.py NUM_GPUS: 8 Loading checkpoint shards: 100%|█████████| 4/4 [04:17<00:00, 64.40s/it] Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. 标题:星际遗产 在未来的地球,人类已经成功地拓展到了星辰大海。在浩瀚的银河系边缘,隐藏着一颗名为“新绿洲”的神秘行星,它拥有适宜生命生存的特殊环境,被联合国命名为“星际遗产”。 故事的主角,艾登·亚历山大,是一位年轻的天体生物学家,他一直对新绿洲充满好奇,梦想揭开其背后 的秘密。他的父亲,一位退役的宇航员,曾在那里进行过一次探险,但那次任务后神秘失踪,留下了一个未解的谜团。 艾登决定继承父亲的遗志,踏上了寻找真相的旅程。他组建了一支由各领域精英组成的探险队伍,包括人工智能专家莉娜、地质学家罗伯特和军事出身的指挥官凯文。他们的目标是通过先进的太空船“曙光号”穿越虫洞,抵达新绿洲。 航行过程中,他们遭遇了未知的宇宙风暴,船员们面临生死考验。艾登凭借他的科学知识和团队的协作,成功稳定了飞船,但他们并未放弃对新绿洲的探索,反而更加坚定了决心。 抵达新绿洲后,他们发现了一个古老的文明遗迹。这是一座巨大的太空站,由高度发达的外星生物建造,他们似乎掌握了超越人类科技的力量。在遗迹中,艾登发现了一份父亲留下的日记,揭示了他的最后发现——这个文明正在面临一场生态危机,为了保护星球,他们选择了自我毁灭。 这个发现让艾登和他的团队陷入了沉思。他们意识到,如果人类继续贪婪地开发宇宙,也许会步上新绿洲文明的后尘。他们决定暂时留在新绿洲,用科技与智慧帮助那里的生物重建家园,同时警告全人类生态平衡的重要性。 在新绿洲的日子里,艾登和他的团队不仅学习了新的科技,也体验了生命的脆弱与坚韧。他们与新绿洲的生物建立了深厚的友谊,甚至开始尝试理解那些外星生物的语言,希望找到和平共存的方法。 最终,艾登以他的勇敢和智慧,向地球发出了关于新绿洲的警告,并提出了“星际和平”的理念。他的故事激励了全球,人类开始反思自己的行为,重新审视对宇宙的态度。 《星际遗产》的故事以艾登在新绿洲的最后一次演讲结束,他的话语回荡在宇宙中:“我们都是星际遗产 的一部分,每一个生命,每一片星域,都值得尊重和保护。让我们一起,为星际的和谐而努力。” real 4m45.451s user 0m56.169s sys 1m7.964s |
从上面结果来看,
总花费时间为:4:45
模型加载时间为4:17
28秒内生成了883个汉字,每秒大约31个汉字,速度比前面快10倍还多
7. 14B的 模型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
from transformers import AutoModelForCausalLM, AutoTokenizer import torch MODEL_NAME = "Qwen/Qwen1.5-14B-Chat" # 定义一个函数来自动配置在多GPU环境下模型各部分的设备分布 def auto_configure_device_map(num_gpus: int): num_trans_layers = 40 # 定义Transformer模型的层数 per_gpu_layers = num_trans_layers / num_gpus # 计算每个GPU应承担的层数 # 初始化设备映射字典,指定一些特定模块应该放置的GPU编号 device_map = { 'model.embed_tokens': 0, # 嵌入层放在第一个GPU上 'model.norm': num_gpus-1, # 最后一个正则化层放在最后一个GPU上 'lm_head': 0 # 语言模型头(用于预测下一个词的层)放在最后一个GPU上 } # 将Transformer模型的每一层分配给一个GPU for i in range(num_trans_layers): device_map[f'model.layers.{i}'] = int(i//per_gpu_layers) return device_map # 检测可用的GPU数量 NUM_GPUS = torch.cuda.device_count() print(f"NUM_GPUS: {NUM_GPUS}") # 如果有可用的GPU,则基于GPU数量自动配置设备映射;否则不使用设备映射 device_map = auto_configure_device_map(NUM_GPUS) if NUM_GPUS > 0 else None # 如果有可用的GPU,则使用第一个GPU;否则使用CPU device = torch.device("cuda") if NUM_GPUS > 0 else torch.device("cpu") # 根据是否使用GPU设置数据类型(半精度或全精度) device_dtype = torch.float16 if NUM_GPUS > 0 else torch.float model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, trust_remote_code=True, torch_dtype=device_dtype, attn_implementation="flash_attention_2", device_map=device_map) # 加载分词器和模型,指定设备映射和数据类型 tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True) model = model.eval() prompt = "写一个2万字的有头有尾的短篇科幻小说." messages = [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": prompt} ] text = tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True ) model_inputs = tokenizer([text], return_tensors="pt").to(device) generated_ids = model.generate( model_inputs.input_ids, max_new_tokens=20000 ) generated_ids = [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) ] response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] print(response) |
运行结果如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
time python test05-14B.py NUM_GPUS: 8 Loading checkpoint shards: 100%|███████████████| 8/8 [04:20<00:00, 32.62s/it] Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. 很抱歉,由于文本格式限制,我无法一次性提供一篇2万字的完整短篇科幻小说。但我可以帮你构思并给出一个大概的故事 框架和部分内容,你可以根据这个框架自行扩展。如果你需要简短的片段或故事大纲,以下是一个示例: 标题:《星际信使》 开头: 在遥远的未来,地球联盟的科学家们发现了一种新型能源——量子纠缠星尘,它能为星际旅行提供无限可能。主人公艾登·雷 诺兹,一名年轻的宇航员,被选中成为首批使用这种能源的星际信使。 正文: 1. 艾登接受任务,驾驶"星际号"飞船离开地球,目标是探索新发现的星系。他的任务是在宇宙中传递科学知识,促进文明 间的交流。 2. 在旅途中,艾登遭遇未知的外星生物——赛伦人,他们对地球文明充满好奇,但又因误解而敌视人类。艾登通过量子纠缠 星尘与地球进行即时通讯,请求援助。 3. 地球科学家利用星尘技术解读了赛伦人的语言,成功传达了和平的信息,避免了一场星际冲突。 4. 在接下来的旅程中,艾登见证了各种奇特的星球生态,学习了多元文明,同时也传播了人类的知识和价值观。 高潮: 艾登在一次意外中发现了一个被遗忘的遗迹,那是一个高度发达的古代文明,他们曾试图用星尘实现宇宙大一统,却因为过度依赖而导致种族衰落。艾登从中领悟到平衡和可持续发展的真谛。 结尾: 艾登带着这个教训回到地球,他向联盟提出关于星尘使用的谨慎建议,倡导人类在追求科技进步的同时,也要尊重自然、平衡发展。他的经历引发了全球的反思,星际信使计划也由此变得更加明智和人性化。 这个框架只是一个大概的构思,你可以根据自己的想象和创作添加细节,每个章节都可以进一步扩展,形成一部完整的2万 字短篇科幻小说。祝你写作顺利! real 10m45.922s user 7m3.979s sys 2m21.686s |
从上面结果来看,
总花费时间为:10:45
模型加载时间为4:20
6分钟内生成了724个汉字,每秒大约1.17个汉字,速度比较慢?
8. 14B 强制使用2张卡装载
单个24G的RTX 4090 无法装载14B的模型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
from transformers import AutoModelForCausalLM, AutoTokenizer import torch MODEL_NAME = "Qwen/Qwen1.5-14B-Chat" # 定义一个函数来自动配置在多GPU环境下模型各部分的设备分布 def auto_configure_device_map(num_gpus: int): num_trans_layers = 40 # 定义Transformer模型的层数 per_gpu_layers = num_trans_layers / num_gpus # 计算每个GPU应承担的层数 # 初始化设备映射字典,指定一些特定模块应该放置的GPU编号 device_map = { 'model.embed_tokens': 0, # 嵌入层放在第一个GPU上 'model.norm': num_gpus-1, # 最后一个正则化层放在最后一个GPU上 'lm_head': 0 # 语言模型头(用于预测下一个词的层)放在最后一个GPU上 } # 将Transformer模型的每一层分配给一个GPU for i in range(num_trans_layers): device_map[f'model.layers.{i}'] = int(i//per_gpu_layers) return device_map # 检测可用的GPU数量 NUM_GPUS = torch.cuda.device_count() print(f"NUM_GPUS: {NUM_GPUS}") # 强制装载到2张卡里面 NUM_GPUS=2 # 如果有可用的GPU,则基于GPU数量自动配置设备映射;否则不使用设备映射 device_map = auto_configure_device_map(NUM_GPUS) if NUM_GPUS > 0 else None # 如果有可用的GPU,则使用第一个GPU;否则使用CPU device = torch.device("cuda") if NUM_GPUS > 0 else torch.device("cpu") # 根据是否使用GPU设置数据类型(半精度或全精度) device_dtype = torch.float16 if NUM_GPUS > 0 else torch.float model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, trust_remote_code=True, torch_dtype=device_dtype, attn_implementation="flash_attention_2", device_map=device_map) # 加载分词器和模型,指定设备映射和数据类型 tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True) model = model.eval() prompt = "写一个2万字的有头有尾的短篇科幻小说." messages = [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": prompt} ] text = tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True ) model_inputs = tokenizer([text], return_tensors="pt").to(device) generated_ids = model.generate( model_inputs.input_ids, max_new_tokens=20000 ) generated_ids = [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) ] response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] print(response) |
运行结果如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
time python test05-14B-2.py NUM_GPUS: 8 Loading checkpoint shards: 100%|████| 8/8 [07:34<00:00, 56.79s/it] Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. 很抱歉,由于文本长度限制,我无法在这里直接为您创作一篇完整的2万字短篇科幻小说。但我可以为您 提供一个故事大纲和部分开头,您可以根据这个大纲自行扩展或者邀请专业作家帮助您完成。以下是一个基本的框架: 标题:《星际编年史:时间裂缝》 故事大纲: 1. 开场:在不远的未来,人类成功实现了星际旅行,地球联合政府成立了星际探索队"曙光号"。主角, 年轻而富有才华的科学家艾伦·瑞恩被选中加入。 2. 发现:曙光号在一次探索中发现了一个神秘的时间裂缝,它连接着未知的维度。 3. 探索:艾伦带领团队深入裂缝,遭遇时间悖论和异次元生物,他们必须解开这些谜团以防止历史被改 变。 4. 冲突:在探索过程中,艾伦意外触发了时间连锁反应,他被困在过去,必须寻找回到现实的方法。 5. 内心成长:在过去的经历中,艾伦面对个人选择与责任的考验,他的信念和智慧成为他突破困境的关 键。 6. 转折点:艾伦通过与过去的自己交谈,意识到只有牺牲一部分记忆,才能修复时间线。 7. 结局:艾伦决定牺牲,成功回到现代,但失去了一些记忆。他分享了这次经历,引发了对时间、记忆 和宇宙真理的新思考。 开头(约1000字): 在2199年的地球联合政府星际探索基地,艾伦·瑞恩博士站在巨大的全息投影屏幕前,他的眼神专注而坚 定。作为“曙光号”星际探索队的一员,他即将带领团队启程,揭开宇宙的未知面纱。然而,他们此次的任务并非单纯的探索,而是寻找传说中的时间裂缝——一种能穿越时间和空间的神秘现象。 “曙光号”在宇宙中闪烁,像一颗璀璨的星辰划破黑暗。艾伦凝视着星图,心中充满了期待和紧张。他们即将面对的是未知的挑战,还是一个改变人类命运的机会?一切,只在一刹那间。 当他们的飞船穿越星系,一个前所未见的光晕突然出现,如同一道时空裂痕,引向一个充满谜团的领域。艾伦深吸一口气,他知道,他们已经踏上了这场史诗般的旅程的起点... 接下来的内容需要您根据这个大纲继续展开,构建情节,塑造角色,增加细节,让故事更加丰富和完整。祝您写作愉快! real 8m23.270s user 1m33.979s sys 2m6.338s |
从上面结果来看,
总花费时间为:8:23
模型加载时间为7:34
49秒内生成了877个汉字,每秒大约17个汉字,速度比前面快10倍
8.1. 14B 强制使用1张卡装载,8位量化
使用 1 张24G 装载,需要使用 BitsAndBytesConfig 进行8位量化,大约需要18G的GPU内存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig import torch import time MODEL_NAME = "Qwen/Qwen1.5-14B-Chat" # 检测可用的GPU数量 NUM_GPUS = torch.cuda.device_count() print(f"NUM_GPUS: {NUM_GPUS}") # 如果有可用的GPU,则使用第一个GPU;否则使用CPU device = torch.device("cuda") if NUM_GPUS > 0 else torch.device("cpu") # 根据是否使用GPU设置数据类型(半精度或全精度) device_dtype = torch.float16 if NUM_GPUS > 0 else torch.float quantization_config = BitsAndBytesConfig(load_in_8bit=True) # 获取起始时间戳 start_time = time.time() model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, trust_remote_code=True, torch_dtype=device_dtype, attn_implementation="flash_attention_2", quantization_config=quantization_config, device_map="cuda:0") # 加载分词器和模型,指定设备映射和数据类型 tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True) model = model.eval() end_time = time.time() elapsed_time = end_time - start_time print(f"Load Model Time: {elapsed_time} seconds") start_time2 = time.time() prompt = "写一个1万字的有头有尾的短篇科幻小说." messages = [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": prompt} ] text = tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True ) model_inputs = tokenizer([text], return_tensors="pt").to(device) generated_ids = model.generate( model_inputs.input_ids, max_new_tokens=10000 ) end_time2 = time.time() elapsed_time2 = end_time2 - start_time2 elapsed_time = end_time2 - start_time num_tokens_generated = len(generated_ids[0]) - len(model_inputs.input_ids[0]) tokens_per_second = num_tokens_generated / elapsed_time2 generated_ids = [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) ] response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] print(response) print(f"Generated Tokens: {num_tokens_generated}") print(f"Tokens per second: {tokens_per_second}") print(f"Total Generation Time: {elapsed_time2} seconds") |
运行结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
time python test05-14B-3.py NUM_GPUS: 8 Loading checkpoint shards: 100%|███████████| 8/8 [10:01<00:00, 75.17s/it] Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. Load Model Time: 604.6261560916901 seconds 很抱歉,由于文本格式限制,我无法一次性提供一篇一万字的完整短篇科幻小说。但我可以为你提供一个大概的故事框架和开头部分,你可以根据这个框架自行扩展或请专业作家进行创作。 标题:《星际编年史:时间裂痕》 --- 在遥远的未来,地球联盟的科学家们发现了一种名为"时空矩阵"的新技术,它能打开通往宇宙深处的时间通道。主角,年轻的物理学家艾登·哈特,是这项研究的关键成员,他渴望探索未知,破解宇宙的秘密。 --- 【第一章:启程】 艾登站在"时光号"飞船的指挥台上,心跳加速。他启动了时空矩阵,一道璀璨的光束划破夜空,他们被吸入了时间与空间的漩涡。穿越了几千年,他们降落在一颗陌生的星球——Zephyria,那里的文明正处在科技的黎明期。 --- 【第二章:异世界历险】 艾登伪装成Zephyrians的学者,开始调查他们的历史。然而,他意外地发现了一个关于时间裂痕的古老传说,这可能与他们文明的衰落有关。他决定寻找并修复这个裂痕,以防止灾难的发生。 --- 【第三章:危机四伏】 在寻找线索的过程中,艾登遭遇了各种危险,包括敌对势力的追捕和神秘力量的阻挠。他的团队成员逐一倒下,他独自面对挑战,内心充满了决心。 --- 【第四章:时间的抉择】 艾登在时间裂痕前做出了艰难的选择:牺牲自己关闭裂痕,保护整个宇宙的时间线,还是坚持回到地球,将这个秘密带回去改变人类的命运? --- 【尾声:归途与启示】 艾登选择关闭裂痕,但他并未消失,而是化为一道光,穿越时空回到了"时光号"。他带回的信息改变了地球联盟对时间旅行的理解,人类开始谨慎地对待时间,避免潜在的灾难。 --- 这个故事只是一个大纲,你可以根据需要添加更多的细节、角色发展和情节转折。希望对你有所帮助! Generated Tokens: 437 Tokens per second: 3.273142501998678 Total Generation Time: 133.51083850860596 seconds real 12m20.918s user 2m58.178s sys 1m54.848s |
8.2. 14B 强制使用1张卡装载,4位量化
使用 1 张24G 装载,需要使用 BitsAndBytesConfig 进行4位量化,大约需要10GB的GPU内存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig import torch import time MODEL_NAME = "Qwen/Qwen1.5-14B-Chat" # 检测可用的GPU数量 NUM_GPUS = torch.cuda.device_count() print(f"NUM_GPUS: {NUM_GPUS}") # 如果有可用的GPU,则使用第一个GPU;否则使用CPU device = torch.device("cuda") if NUM_GPUS > 0 else torch.device("cpu") # 根据是否使用GPU设置数据类型(半精度或全精度) device_dtype = torch.float16 if NUM_GPUS > 0 else torch.float quantization_config = BitsAndBytesConfig(load_in_4bit=True) # 获取起始时间戳 start_time = time.time() model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, trust_remote_code=True, torch_dtype=device_dtype, attn_implementation="flash_attention_2", quantization_config=quantization_config, device_map="cuda:0") # 加载分词器和模型,指定设备映射和数据类型 tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True) model = model.eval() end_time = time.time() elapsed_time = end_time - start_time print(f"Load Model Time: {elapsed_time} seconds") start_time2 = time.time() prompt = "写一个1万字的有头有尾的短篇科幻小说." messages = [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": prompt} ] text = tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True ) model_inputs = tokenizer([text], return_tensors="pt").to(device) generated_ids = model.generate( model_inputs.input_ids, max_new_tokens=10000 ) end_time2 = time.time() elapsed_time2 = end_time2 - start_time2 elapsed_time = end_time2 - start_time num_tokens_generated = len(generated_ids[0]) - len(model_inputs.input_ids[0]) tokens_per_second = num_tokens_generated / elapsed_time2 generated_ids = [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) ] response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] print(response) print(f"Generated Tokens: {num_tokens_generated}") print(f"Tokens per second: {tokens_per_second}") print(f"Total Generation Time: {elapsed_time2} seconds") |
运行结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
time python test05-14B-4.py NUM_GPUS: 8 Loading checkpoint shards: 100%|███████| 8/8 [07:55<00:00, 59.49s/it] Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. Load Model Time: 479.92521357536316 seconds /home/tony/anaconda3/envs/Jamba/lib/python3.11/site-packages/bitsandbytes/nn/modules.py:391: UserWarning: Input type into Linear4bit is torch.float16, but bnb_4bit_compute_dtype=torch.float32 (default). This will lead to slow inference or training speed. warnings.warn('Input type into Linear4bit is torch.float16, but bnb_4bit_compute_dtype=torch.float32 (default). This will lead to slow inference or training speed.') 标题:星际穿越的遗产 在遥远的未来,地球已不再是人类的唯一家园。我们开拓了新的星系,建立了星际联邦,科技发展到了前所未有的高度。然而,在这个故事中,我们将聚焦在一个名叫"新希望星"的星球上,那里的居民们正在寻找一项神秘遗产,它可能改变他们整个文明的命运。 第一章:新希望星 新希望星,一颗位于银河边缘的宜居星球,其表面覆盖着繁茂的森林和神秘的遗迹。这里的居民,赛尔人,是一个拥有先进生物科技的种族,他们的城市隐藏在地下,以避免太阳辐射的侵扰。 第二章:遗产的传说 古老的传说中,赛尔人的祖先在星际旅行中发现了一项神秘的遗产,被称为“光谱之心”。这颗心形装置据说拥有无尽的知识和力量,能引领人类走向更高的文明阶段。然而,数百年来,没有任何人能找到它的踪迹。 第三章:失落的线索 一位名叫艾丽亚的年轻赛尔科学家,对这个传说充满了好奇。她决心找到“光谱之心”,希望能为她的星球带来和平与繁荣。她开始研究古代文献,寻找可能的线索。 第四章:冒险启程 艾丽亚组建了一个探险队,包括勇敢的飞行员瑞恩、智慧的工程师莉娜和一名神秘的外星盟友卡特。他们踏上了一场寻找“光谱之心”的旅程,穿越未知的星系,遭遇了各种危险。 第五章至第九章:星际挑战 他们在旅途中遭遇了外星生物的袭击,经历了黑洞边缘的险境,甚至在一次意外中发现了关于“光谱之心”的更深层信息。每一次挑战都让他们的友情更加深厚,也使他们更接近目标。 第十章:谜团揭晓 经过一系列艰难的探索,他们终于在一个古老的遗迹中找到了“光谱之心”。原来,这并非一件武器或力量源泉,而是一套教导智慧和道德伦理的课程。艾丽亚意识到,真正的遗产并非物质,而是理解和尊重宇宙万物的知识。 第十一章:新希望 他们带着这个新发现回到新希望星,分享了他们的发现。人们开始理解到,真正的进步并非来自于力量,而是来自内心的和谐与爱。赛尔人的社会开始发生深刻的变化,他们学会了共处,尊重差异,和平共生。 第十二章:尾声 艾丽亚成为了一个传奇,她的故事激励了新一代的赛尔人。他们不再追求物质的力量,而是追求心灵的成长和宇宙的理解。新希望星在“光谱之心”的影响下,成为了银河系的一颗璀璨明珠,象征着和平与智慧的光芒。 故事结束,但赛尔人的旅程并未停止,他们继续探索宇宙,寻找更多的知识和智慧,他们的故事在星际间流传,成为了一个永恒的传说。 Generated Tokens: 596 Tokens per second: 13.52436708752385 Total Generation Time: 44.06860566139221 seconds real 8m46.833s user 1m34.053s sys 1m49.504s |
前面有警告,我们去除警告,修改如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig import torch import time MODEL_NAME = "Qwen/Qwen1.5-14B-Chat" # 检测可用的GPU数量 NUM_GPUS = torch.cuda.device_count() print(f"NUM_GPUS: {NUM_GPUS}") # 如果有可用的GPU,则使用第一个GPU;否则使用CPU device = torch.device("cuda") if NUM_GPUS > 0 else torch.device("cpu") # 根据是否使用GPU设置数据类型(半精度或全精度) device_dtype = torch.float32 if NUM_GPUS > 0 else torch.float quantization_config = BitsAndBytesConfig(load_in_4bit=True) # 获取起始时间戳 start_time = time.time() model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, trust_remote_code=True, torch_dtype=device_dtype, quantization_config=quantization_config, device_map="cuda:0") # 加载分词器和模型,指定设备映射和数据类型 tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True) model = model.eval() end_time = time.time() elapsed_time = end_time - start_time print(f"Load Model Time: {elapsed_time} seconds") start_time2 = time.time() prompt = "写一个1万字的有头有尾的短篇科幻小说." messages = [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": prompt} ] text = tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True ) model_inputs = tokenizer([text], return_tensors="pt").to(device) generated_ids = model.generate( model_inputs.input_ids, max_new_tokens=10000 ) end_time2 = time.time() elapsed_time2 = end_time2 - start_time2 elapsed_time = end_time2 - start_time num_tokens_generated = len(generated_ids[0]) - len(model_inputs.input_ids[0]) tokens_per_second = num_tokens_generated / elapsed_time2 generated_ids = [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) ] response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] print(response) print(f"Generated Tokens: {num_tokens_generated}") print(f"Tokens per second: {tokens_per_second}") print(f"Total Generation Time: {elapsed_time2} seconds") |
运行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
time python test05-14B-4.py NUM_GPUS: 8 Loading checkpoint shards: 100%|████████████| 8/8 [08:18<00:00, 62.30s/it] Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. Load Model Time: 501.56107807159424 seconds 标题:星际之谜:光年之外的遗产 在遥远的未来,地球已经成为了人类文明的摇篮。科技的发展使得人类探索宇宙的步伐日益加快,星际旅行变得寻常。我们的主人公,年轻的天文学家艾米丽·哈特,是一个对未知充满好奇的探险者,她被选中 加入了一项名为“光年计划”的太空探索任务。 故事开始: 第一章:启程的号角 艾米丽站在巨大的星际飞船“希望号”上,望着那颗蓝色星球渐行渐远。她的任务是前往最近发现的一颗名为“伊甸星”的神秘星球,寻找可能存在的外星文明遗迹。船员们紧张而兴奋,每个人都明白这是一次改变历史的冒险。 第二章:未知的伊甸星 经过数月的旅行,希望号抵达了伊甸星。艾米丽带领团队着陆,他们发现了一个被古老能量护盾保护的遗迹,这让她想起传说中的“星际遗产”。 第三章:遗产的秘密 艾米丽和团队深入遗迹,发现了一系列高科技设备,其中一台神秘的“时间共鸣器”引起了他们的注意。他们意识到,这个遗产可能与时间旅行有关。 第四章:时间的试炼 艾米丽决定激活时间共鸣器,试图穿越时间以了解更多关于伊甸星文明的信息。然而,每一次尝试都引发了一连串的时空混乱,他们陷入了无法预知的危险。 第五章:时空迷宫 在混乱中,艾米丽意外地回到了过去,遇见了年轻的自己。她们联手解开了一道道谜题,揭示了伊甸星文明的真相——他们曾试图阻止一场毁灭性的灾难,但失败了。 第六章:使命与抉择 艾米丽意识到,只有阻止这场灾难,才能修复时空,回到现实。她决定牺牲自己,将年轻的自己送回过去,拯救伊甸星。 第七章:光年的决断 艾米丽在最后关头,启动了时间共鸣器,将自己的意识与过去的自己融合。一道耀眼的光芒闪过,她消失在了时间的长河中。 尾声:永恒的遗产 当艾米丽重新睁开眼睛,发现自己回到了希望号上,伊甸星的灾难已被阻止。她的牺牲拯救了两个世界,她的名字被镌刻在星际历史的篇章中。虽然她失去了肉身,但她的精神和遗产永远留在了光年之外的星海。 艾米丽的故事告诉我们,勇敢面对未知,坚守正义,即使付出生命的代价,也能创造奇迹。她用生命编织出的传奇,将激励后世的探险者继续探索宇宙的奥秘。 Generated Tokens: 557 Tokens per second: 15.294492646068159 Total Generation Time: 36.41833782196045 seconds real 9m0.806s user 1m31.212s sys 1m57.739s |
8.3. 保存 14B 4位量化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig import torch import time MODEL_NAME = "Qwen/Qwen1.5-14B-Chat" # 检测可用的GPU数量 NUM_GPUS = torch.cuda.device_count() print(f"NUM_GPUS: {NUM_GPUS}") # 如果有可用的GPU,则使用第一个GPU;否则使用CPU device = torch.device("cuda") if NUM_GPUS > 0 else torch.device("cpu") # 根据是否使用GPU设置数据类型(半精度或全精度) device_dtype = torch.float32 if NUM_GPUS > 0 else torch.float quantization_config = BitsAndBytesConfig(load_in_4bit=True) # 获取起始时间戳 start_time = time.time() model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, trust_remote_code=True, torch_dtype=device_dtype, quantization_config=quantization_config, device_map="cuda:0") # 加载分词器和模型,指定设备映射和数据类型 tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True) model = model.eval() end_time = time.time() elapsed_time = end_time - start_time print(f"Load Model Time: {elapsed_time} seconds") start_time2 = time.time() prompt = "写一个1万字的有头有尾的短篇科幻小说." messages = [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": prompt} ] text = tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True ) model_inputs = tokenizer([text], return_tensors="pt").to(device) generated_ids = model.generate( model_inputs.input_ids, max_new_tokens=10000 ) end_time2 = time.time() elapsed_time2 = end_time2 - start_time2 elapsed_time = end_time2 - start_time num_tokens_generated = len(generated_ids[0]) - len(model_inputs.input_ids[0]) tokens_per_second = num_tokens_generated / elapsed_time2 generated_ids = [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) ] response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] print(response) print(f"Generated Tokens: {num_tokens_generated}") print(f"Tokens per second: {tokens_per_second}") print(f"Total Generation Time: {elapsed_time2} seconds") print(f"config.save_pretrained") model.config.save_pretrained('Qwen/Qwen1.5-14B-Chat-Int4') print(f"model.save_pretrained") model.save_pretrained('Qwen/Qwen1.5-14B-Chat-Int4') print(f"tokenizer.save_pretrained") tokenizer.save_pretrained('Qwen/Qwen1.5-14B-Chat-Int4') |
运行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
time python test05-14B-5.py NUM_GPUS: 8 Loading checkpoint shards: 12%|███▊ | 1/8 [01:09<08:07, 69.59s/it] Loading checkpoint shards: 100%|███████████| 8/8 [08:21<00:00, 62.67s/it] Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. Load Model Time: 504.4282364845276 seconds 标题:星际迷航:新秩序 在遥远的未来,人类已经超越了地球的束缚,建立了庞大的星际联邦。故事的主人公,艾登·雷诺兹,是 一位年轻的星际飞行员,他的代号“幽灵”,是联邦舰队中最出色的侦察员。 第一章:启程 在星系边缘的霍尔顿基地,艾登正准备执行一项秘密任务。他站在飞船“幽灵之翼”前,凝视着星空,心中充满了未知的紧张与期待。他的任务是潜入神秘的Zephyr星域,寻找传说中的“新秩序”能源矿石。 第二章:新秩序 Zephyr星域,一个被遗忘的区域,隐藏着一种名为“新秩序”的能源,据说能为人类科技带来革命性的突破。艾登深入星域,遭遇了从未见过的异形生物和险恶环境,但他凭借坚韧的决心和卓越的驾驶技术,一一克服。 第三章:背叛 在一次遭遇战中,艾登发现了一个惊人的事实——他的指挥官,杰森·哈特,竟是新秩序能源的幕后黑手。 杰森企图利用这种能源控制星际联邦,艾登决定独自阻止他。 第四章:孤独的战斗 艾登与杰森展开了激烈的追逐战,他一边躲避杰森的追捕,一边向联邦发出警告。他在星空中穿梭,每一次逃脱都是一场生死考验。 第五章:最终决战 在新秩序能源的核心区域,艾登与杰森进行了一场决定人类命运的决斗。艾登用智慧和勇气挫败了杰森,成功阻止了他利用能源的计划。 第六章:新生 联邦舰队闻讯而来,他们逮捕了杰森,并修复了被破坏的能源设施。艾登因功勋卓著,被授予“星际英雄”勋章。他回到地球,成为新一代年轻人的榜样。 尾声:未来的希望 艾登的故事激励着人们,人类继续探索宇宙,追求和平与进步。而新秩序能源,虽然一度被黑暗所利用,但最终还是成为了推动科技发展的强大动力。艾登·雷诺兹的名字,将永远镌刻在星际历史的篇章中。 这部一万字的短篇科幻小说,以艾登·雷诺兹的冒险旅程为主线,展现了人类面对未知挑战时的勇气与智 慧,同时也探讨了科技与人性的复杂关系。 Generated Tokens: 507 Tokens per second: 17.584081014282045 Total Generation Time: 28.832897186279297 seconds config.save_pretrained model.save_pretrained tokenizer.save_pretrained real 10m23.330s user 1m30.706s sys 2m1.814s ls -l Qwen/Qwen1.5-14B-Chat total 27681848 -rwxrwxrwx 1 tony tony 6896 Mar 30 11:49 LICENSE -rwxrwxrwx 1 tony tony 4346 Mar 30 11:49 README.md -rwxrwxrwx 1 tony tony 663 Mar 30 11:49 config.json -rwxrwxrwx 1 tony tony 243 Mar 30 11:49 generation_config.json -rwxrwxrwx 1 tony tony 1519 Mar 30 11:49 gitattributes -rwxrwxrwx 1 tony tony 1671839 Mar 30 11:49 merges.txt -rwxrwxrwx 1 tony tony 3938903200 Mar 30 11:59 model-00001-of-00008.safetensors -rwxrwxrwx 1 tony tony 3975760472 Mar 30 11:59 model-00002-of-00008.safetensors -rwxrwxrwx 1 tony tony 3940360872 Mar 30 12:00 model-00003-of-00008.safetensors -rwxrwxrwx 1 tony tony 3923300576 Mar 30 12:00 model-00004-of-00008.safetensors -rwxrwxrwx 1 tony tony 3923300568 Mar 30 12:00 model-00005-of-00008.safetensors -rwxrwxrwx 1 tony tony 3975760552 Mar 30 12:00 model-00006-of-00008.safetensors -rwxrwxrwx 1 tony tony 3100115576 Mar 30 11:59 model-00007-of-00008.safetensors -rwxrwxrwx 1 tony tony 1557135488 Mar 30 11:55 model-00008-of-00008.safetensors -rwxrwxrwx 1 tony tony 39584 Mar 30 11:50 model.safetensors.index.json -rwxrwxrwx 1 tony tony 7028015 Mar 30 11:50 tokenizer.json -rwxrwxrwx 1 tony tony 1402 Mar 30 11:50 tokenizer_config.json -rwxrwxrwx 1 tony tony 2776833 Mar 30 11:50 vocab.json ls -l Qwen/Qwen1.5-14B-Chat-Int4/ total 13024520 -rwxrwxrwx 1 tony tony 80 Mar 30 22:03 added_tokens.json -rwxrwxrwx 1 tony tony 1187 Mar 30 22:02 config.json -rwxrwxrwx 1 tony tony 243 Mar 30 22:02 generation_config.json -rwxrwxrwx 1 tony tony 1671853 Mar 30 22:03 merges.txt -rwxrwxrwx 1 tony tony 4986994946 Mar 30 22:02 model-00001-of-00003.safetensors -rwxrwxrwx 1 tony tony 4967849904 Mar 30 22:03 model-00002-of-00003.safetensors -rwxrwxrwx 1 tony tony 3370646086 Mar 30 22:03 model-00003-of-00003.safetensors -rwxrwxrwx 1 tony tony 120934 Mar 30 22:03 model.safetensors.index.json -rwxrwxrwx 1 tony tony 367 Mar 30 22:03 special_tokens_map.json -rwxrwxrwx 1 tony tony 7028015 Mar 30 22:03 tokenizer.json -rwxrwxrwx 1 tony tony 1414 Mar 30 22:03 tokenizer_config.json -rwxrwxrwx 1 tony tony 2776833 Mar 30 22:03 vocab.json ( |
8.4. 加载 14B 4位量化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig import torch import time MODEL_NAME = "Qwen/Qwen1.5-14B-Chat-Int4" # 检测可用的GPU数量 NUM_GPUS = torch.cuda.device_count() print(f"NUM_GPUS: {NUM_GPUS}") # 如果有可用的GPU,则使用第一个GPU;否则使用CPU device = torch.device("cuda") if NUM_GPUS > 0 else torch.device("cpu") start_time = time.time() model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, trust_remote_code=True, device_map="cuda:0") # 加载分词器和模型,指定设备映射和数据类型 tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True) model = model.eval() end_time = time.time() elapsed_time = end_time - start_time print(f"Load Model Time: {elapsed_time} seconds") start_time2 = time.time() prompt = "写一个1万字的有头有尾的短篇科幻小说." messages = [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": prompt} ] text = tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True ) model_inputs = tokenizer([text], return_tensors="pt").to(device) generated_ids = model.generate( model_inputs.input_ids, max_new_tokens=10000 ) end_time2 = time.time() elapsed_time2 = end_time2 - start_time2 elapsed_time = end_time2 - start_time num_tokens_generated = len(generated_ids[0]) - len(model_inputs.input_ids[0]) tokens_per_second = num_tokens_generated / elapsed_time2 generated_ids = [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) ] response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] print(response) print(f"Generated Tokens: {num_tokens_generated}") print(f"Tokens per second: {tokens_per_second}") print(f"Total Generation Time: {elapsed_time2} seconds") |
运行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
time python test05-14B-6.py NUM_GPUS: 8 Loading checkpoint shards: 100%|█████████████████████████████| 3/3 [06:06<00:00, 122.18s/it] Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. Load Model Time: 369.8666627407074 seconds /home/tony/anaconda3/envs/Jamba/lib/python3.11/site-packages/bitsandbytes/nn/modules.py:391: UserWarning: Input type into Linear4bit is torch.float16, but bnb_4bit_compute_dtype=torch.float32 (default). This will lead to slow inference or training speed. warnings.warn('Input type into Linear4bit is torch.float16, but bnb_4bit_compute_dtype=torch.float32 (default). This will lead to slow inference or training speed.') 标题:星际迷航:新秩序 在遥远的未来,人类已经掌握了星际旅行的技术,建立了庞大的星际联邦。故事的主人公,艾瑞克·哈特 ,是一位年轻的星际探索者,他的梦想是成为联邦的旗舰——“新秩序号”上的舰长。 第一章:启航 艾瑞克站在新秩序号的舰桥上,望着那颗蓝色的地球,心中满是对家乡的眷恋。然而,他的使命是寻找可能存在的外星生命迹象,这是他作为探索者的使命,也是他的荣誉。随着指挥官的一声令下,飞船犹如一道流星划破夜空,离开了地球。 第二章:未知的星系 穿越了数光年的距离,他们来到了一个全新的星系。艾瑞克和他的团队发现了一颗名为Zephyr的行星,其表面的生态系统与地球截然不同,充满了未知的生物和奇异的植物。他们开始了深入探索,期待找到生命的痕迹。 第三章:意外的发现 在Zephyr行星的深处,他们发现了一个古老的遗迹,一种高度发达的文明曾在这里存在。然而,这个文明似乎已经消失,只留下了一种神秘的能量晶体,这可能是他们生存的关键。 第四章:危机来临 在研究能量晶体的过程中,一艘敌对势力的飞船突然出现,他们意图夺取能量晶体。一场激烈的战斗在星空中展开,新秩序号凭借其先进的科技勉强抵挡住了攻击。 第五章:忠诚与背叛 在战斗中,艾瑞克的好友、副舰长丽莎因为被敌方俘虏,被迫加入了敌人。她向艾瑞克透露了一个惊人的秘密:这个能量晶体可能引发宇宙的毁灭,她的目标只是阻止它落入错误的手中。 第六章:决定命运的选择 艾瑞克面临着艰难的抉择:保护人类,还是保护宇宙的安全?他决定独自面对危险,去摧毁能量晶体,同时设法营救丽莎。 第七章:最后的决战 艾瑞克成功摧毁了能量晶体,但也牺牲了自己。他的勇敢行为感动了丽莎,她决定背叛敌对势力,回到新秩序号。他们带着丽莎的牺牲和艾瑞克的遗志,返回地球,将真相告诉了联邦。 尾声:新的开始 虽然艾瑞克没有回来,但他的精神激励了新一代的探索者。新秩序号继续在星海中航行,寻找更多的知识和智慧。丽莎成为了新一任舰长,带领着人们走向未知,铭记着艾瑞克的勇气和决心。 在艾瑞克的故事中,我们看到了人类对未知的渴望,对正义的坚持,以及对生命的尊重。他们的冒险旅程还在继续,而他们的故事,将成为星际历史的一部分。 Generated Tokens: 575 Tokens per second: 14.387834139574515 Total Generation Time: 39.964319467544556 seconds config.save_pretrained model.save_pretrained tokenizer.save_pretrained real 7m57.178s user 0m51.384s sys 0m44.998s |
9. 我们再试试最大个的72B
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
from transformers import AutoModelForCausalLM, AutoTokenizer import torch MODEL_NAME = "Qwen/Qwen1.5-72B-Chat" # 定义一个函数来自动配置在多GPU环境下模型各部分的设备分布 def auto_configure_device_map(num_gpus: int): num_trans_layers = 80 # 定义Transformer模型的层数 per_gpu_layers = num_trans_layers / num_gpus # 计算每个GPU应承担的层数 # 初始化设备映射字典,指定一些特定模块应该放置的GPU编号 device_map = { 'model.embed_tokens': 0, # 嵌入层放在第一个GPU上 'model.norm': num_gpus-1, # 最后一个正则化层放在最后一个GPU上 'lm_head': 0 # 语言模型头(用于预测下一个词的层)放在最后一个GPU上 } # 将Transformer模型的每一层分配给一个GPU for i in range(num_trans_layers): device_map[f'model.layers.{i}'] = int(i//per_gpu_layers) return device_map # 检测可用的GPU数量 NUM_GPUS = torch.cuda.device_count() print(f"NUM_GPUS: {NUM_GPUS}") # 如果有可用的GPU,则基于GPU数量自动配置设备映射;否则不使用设备映射 device_map = auto_configure_device_map(NUM_GPUS) if NUM_GPUS > 0 else None # 如果有可用的GPU,则使用第一个GPU;否则使用CPU device = torch.device("cuda") if NUM_GPUS > 0 else torch.device("cpu") # 根据是否使用GPU设置数据类型(半精度或全精度) device_dtype = torch.float16 if NUM_GPUS > 0 else torch.float model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, trust_remote_code=True, torch_dtype=device_dtype, attn_implementation="flash_attention_2", device_map=device_map) # 加载分词器和模型,指定设备映射和数据类型 tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True) model = model.eval() prompt = "写一个3万字的有头有尾的短篇科幻小说." messages = [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": prompt} ] text = tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True ) model_inputs = tokenizer([text], return_tensors="pt").to(device) generated_ids = model.generate( model_inputs.input_ids, max_new_tokens=32000 ) generated_ids = [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) ] response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] print(response) |
运行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
time python test05-72B.py NUM_GPUS: 8 Loading checkpoint shards: 100%|██████████████| 38/38 [50:34<00:00, 79.87s/it] Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. 对不起,由于文本长度的限制,我无法在这里提供一个完整的3万字的短篇科幻小说。但我可以为你提供一个简短的开头和 大纲,你可以根据这个大纲自行扩展。 标题:《星际归途》 开头: 在遥远的未来,人类已经建立了跨星际的殖民地。主人公,艾伦·哈特,是一名勇敢的星际探险家,他的任务是寻找新的适 合人类居住的星球。在一次探索中,他的飞船意外坠落在了一个未知的星球上。 大纲: 1. **失落的星球**:艾伦醒来发现自己在一个陌生的环境中,星球的环境与地球截然不同,有独特的生物和奇特的自然现 象。他利用飞船残骸中的设备进行生存和探索。 2. **异星文明**:艾伦发现了一种高度发达的异星文明,他们生活在地下,与星球的环境和谐共生。他试图与他们交流, 但语言和文化的差异使得沟通困难。 3. **科技交换**:艾伦通过画图、手势等方式逐渐与异星生物建立联系,他们分享了部分科技知识,艾伦也教他们人类的 语言和文化。 4. **危机降临**:艾伦发现这个星球正在遭受一种未知病毒的侵袭,这种病毒对异星生物来说是致命的,但对人类无害。 他决定帮助他们寻找解药。 5. **生死抉择**:艾伦利用新学的科技,成功研发出疫苗,但发现这会破坏异星生物的生态平衡。他必须做出选择:拯救 自己,还是拯救这个文明? 6. **星际归途**:艾伦决定牺牲自己,将疫苗留给异星生物。他的故事被异星生物记录下来,成为他们的传说。他的飞船 被修复,设定为自动返回地球的模式。 结尾: 在艾伦的飞船返回地球的那一刻,他的英勇事迹被地球人知晓,他被誉为英雄,他的精神激励着新一代的星际探险者。而那个遥远的星球,也在艾伦的影响下,开始向宇宙发出和平的信号,寻找更多的生命交流。 这是一个大致的故事框架,你可以根据这个框架填充细节,发展角色,描绘场景,增加冲突,使故事更加丰富和引人入胜。 real 54m38.507s user 7m20.744s sys 9m10.919s |
从上面结果来看,
总花费时间为:54:38
模型加载时间为50:34
4分钟内生成了809个汉字,每秒大约3.37个汉字,速度还可以
9.1. 72B 的4位量化并保存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig import torch import time MODEL_NAME = "Qwen/Qwen1.5-72B-Chat" # 检测可用的GPU数量 NUM_GPUS = torch.cuda.device_count() print(f"NUM_GPUS: {NUM_GPUS}") # 如果有可用的GPU,则使用第一个GPU;否则使用CPU device = torch.device("cuda") if NUM_GPUS > 0 else torch.device("cpu") # 根据是否使用GPU设置数据类型(半精度或全精度) device_dtype = torch.float32 if NUM_GPUS > 0 else torch.float quantization_config = BitsAndBytesConfig(load_in_4bit=True) # 获取起始时间戳 start_time = time.time() model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, trust_remote_code=True, torch_dtype=device_dtype, quantization_config=quantization_config, device_map="auto") # 加载分词器和模型,指定设备映射和数据类型 tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True) model = model.eval() end_time = time.time() elapsed_time = end_time - start_time print(f"Load Model Time: {elapsed_time} seconds") start_time2 = time.time() prompt = "写一个1万字的有头有尾的短篇科幻小说." messages = [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": prompt} ] text = tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True ) model_inputs = tokenizer([text], return_tensors="pt").to(device) generated_ids = model.generate( model_inputs.input_ids, max_new_tokens=10000 ) end_time2 = time.time() elapsed_time2 = end_time2 - start_time2 elapsed_time = end_time2 - start_time num_tokens_generated = len(generated_ids[0]) - len(model_inputs.input_ids[0]) tokens_per_second = num_tokens_generated / elapsed_time2 generated_ids = [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) ] response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] print(response) print(f"Generated Tokens: {num_tokens_generated}") print(f"Tokens per second: {tokens_per_second}") print(f"Total Generation Time: {elapsed_time2} seconds") print(f"config.save_pretrained") model.config.save_pretrained('Qwen/Qwen1.5-72B-Chat-Int4') print(f"model.save_pretrained") model.save_pretrained('Qwen/Qwen1.5-72B-Chat-Int4') print(f"tokenizer.save_pretrained") tokenizer.save_pretrained('Qwen/Qwen1.5-72B-Chat-Int4') |
运行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
time python test05-72B-5.py NUM_GPUS: 8 Loading checkpoint shards: 100%|██████████████| 38/38 [48:18<00:00, 76.27s/it] Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. Load Model Time: 2907.2342824935913 seconds 对不起,由于文字长度限制,我无法在这里提供一篇完整的1万字科幻小说。但我可以为你提供一个大纲,你可以根据这 个大纲来扩展你的故事: 标题:《星际归途》 一、开头(1000字) 1. 描述地球的未来,科技高度发达,人类已经成功实现了星际旅行。 2. 主角艾伦,是一位星际探险家,他的任务是寻找新的适合人类居住的星球。 二、冲突(3000字) 1. 艾伦在一次探索中,飞船遭遇未知力量的袭击,被迫降落在一个陌生的星球。 2. 他发现这个星球的生物具有高度智能,且对人类怀有敌意。 3. 飞船损坏严重,修复需要一种当地稀有的元素,艾伦必须与这个星球的生物进行交流和交易。 三、发展(3000字) 1. 艾伦通过学习星球的语言和文化,逐渐赢得了部分生物的信任。 2. 在此过程中,他发现这个星球的生物正面临一场灾难,他们的敌人是一种来自宇宙深处的邪恶力量。 3. 艾伦决定帮助他们,以此换取修复飞船的元素。 四、高潮(1500字) 1. 艾伦带领星球生物与邪恶力量展开决战,他利用飞船的武器系统,成功击退了邪恶力量。 2. 在战斗中,艾伦展现出的人类智慧和勇气,使得星球生物对他产生了深深的敬意。 五、结局(1500字) 1. 星球生物帮助艾伦修复飞船,并赠予他足够的元素。 2. 艾伦告别新朋友,启程返回地球,但他承诺会回来再次访问这个星球。 3. 返回地球后,艾伦的故事激励了全人类,大家更加团结,共同面对未来的挑战。 这只是一个基本的大纲,你可以根据自己的想法添加更多的细节,比如角色的内心挣扎、星球的环境描述、战斗的策略等,以丰富你的故事。 Generated Tokens: 429 Tokens per second: 1.6327658813303874 Total Generation Time: 262.7443437576294 seconds config.save_pretrained model.save_pretrained tokenizer.save_pretrained real 57m57.074s user 13m11.878s sys 28m54.212s |
9.2 加载 72B 4位量化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig import torch import time # 清空 VRAM 缓冲区 torch.cuda.empty_cache() MODEL_NAME = "Qwen/Qwen1.5-72B-Chat-Int4" # 定义一个函数来自动配置在多GPU环境下模型各部分的设备分布 def auto_configure_device_map(num_gpus: int): num_trans_layers = 80 # 定义Transformer模型的层数 per_gpu_layers = num_trans_layers / num_gpus # 计算每个GPU应承担的层数 # 初始化设备映射字典,指定一些特定模块应该放置的GPU编号 device_map = { 'model.embed_tokens': 0, # 嵌入层放在第一个GPU上 'model.norm': 0, # 最后一个正则化层放在第一个GPU上 'lm_head': 0 # 语言模型头(用于预测下一个词的层)放在第一个GPU上 } # 将Transformer模型的每一层分配给一个GPU for i in range(num_trans_layers): device_map[f'model.layers.{i}'] = int(i//per_gpu_layers) return device_map # 检测可用的GPU数量 NUM_GPUS = torch.cuda.device_count() print(f"NUM_GPUS: {NUM_GPUS}") NUM_GPUS = 3 # 如果有可用的GPU,则基于GPU数量自动配置设备映射;否则不使用设备映射 device_map = auto_configure_device_map(NUM_GPUS) if NUM_GPUS > 0 else None # 如果有可用的GPU,则使用第一个GPU;否则使用CPU device = torch.device("cuda") if NUM_GPUS > 0 else torch.device("cpu") start_time = time.time() model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, trust_remote_code=True, device_map=device_map) # 加载分词器和模型,指定设备映射和数据类型 tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True) model = model.eval() end_time = time.time() elapsed_time = end_time - start_time print(f"Load Model Time: {elapsed_time} seconds") start_time2 = time.time() prompt = "写一个1万字的有头有尾的短篇科幻小说." messages = [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": prompt} ] text = tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True ) model_inputs = tokenizer([text], return_tensors="pt").to(device) generated_ids = model.generate( model_inputs.input_ids, max_new_tokens=10000 ) end_time2 = time.time() elapsed_time2 = end_time2 - start_time2 elapsed_time = end_time2 - start_time num_tokens_generated = len(generated_ids[0]) - len(model_inputs.input_ids[0]) tokens_per_second = num_tokens_generated / elapsed_time2 generated_ids = [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) ] response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] print(response) print(f"Generated Tokens: {num_tokens_generated}") print(f"Tokens per second: {tokens_per_second}") print(f"Total Generation Time: {elapsed_time2} seconds") |
运行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
time python test05-72B-6.py NUM_GPUS: 8 Loading checkpoint shards: 100%|██████████████| 10/10 [22:04<00:00, 132.45s/it] Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. Load Model Time: 1328.904905796051 seconds /home/tony/anaconda3/envs/Jamba/lib/python3.11/site-packages/bitsandbytes/nn/modules.py:391: UserWarning: Input type into Linear4bit is torch.float16, but bnb_4bit_compute_dtype=torch.float32 (default). This will lead to slow inference or training speed. warnings.warn('Input type into Linear4bit is torch.float16, but bnb_4bit_compute_dtype=torch.float32 (default). This will lead to slow inference or training speed.') 很抱歉,由于字数限制,我无法在这里提供一篇完整的1万字科幻小说。但我可以为你创作一个简短的开头和结尾,并提 供一个大致的故事情节,你可以根据这个大纲来扩展你的故事。 标题:《星际归途》 开头: 在遥远的未来,人类已经建立了跨星系的殖民地。主角艾伦·哈特,一位天才的星际导航员,负责带领一支探险队寻找新 的适宜居住的星球。在一次意外中,他们的飞船被黑洞吸入,经过了漫长的时空扭曲,他们来到了一个未知的宇宙区域。 情节发展: 艾伦和他的队伍发现,这个宇宙区域与他们所知的宇宙截然不同,物理规则似乎都在这里失效。他们面临着资源枯竭、飞船损坏的困境,同时,他们也发现了这个区域内存在一种高度发达的文明。艾伦与这个文明接触,学习他们的科技,尝试修复飞船。 高潮: 艾伦发现,这个文明正遭受一种名为"暗能量瘟疫"的威胁,这种瘟疫会破坏宇宙的基本结构。艾伦决定帮助他们,他利用自己的知识结合新学的科技,试图找到解决办法。在这个过程中,艾伦的人性和智慧得到了充分的展现,也赢得了这个文明的尊重。 结尾: 在一场壮烈的战斗后,艾伦成功阻止了"暗能量瘟疫"的扩散,但也牺牲了自己。他的勇敢和智慧被全宇宙铭记,他的飞船被改造成了一个移动的博物馆,穿越星系,传播他的故事和人类的精神。而他的队伍,带着艾伦的遗志,找到了新的居住星球,开始了新的生活,他们的冒险和探索,成为了新一代的传说。 这就是《星际归途》的故事大纲,你可以根据这个框架,填充更多的细节,如人物性格塑造、具体事件描绘、情感冲突等,将其发展成一个完整的故事。 Generated Tokens: 393 Tokens per second: 3.4790348195658485 Total Generation Time: 112.9623646736145 seconds real 24m5.878s user 2m5.539s sys 3m35.394s (Jamba) tony@DESKTOP-HHKHPUU:/mnt/d/ai/Qwen$ |