之前分别用numpy实现了mlp,cnn,lstm和bert模型,这周顺带搞一下GPT-2,纯numpy实现,最重要的是可在树莓派上或其他不能安装pytorch的板子上运行,生成数据

gpt-2的mask-multi-headed-self-attention我现在才彻底的明白它是真的牛逼,比bert的multi-headed-self-attention牛的不是一点半点,提出mask的人智商也是相当高了

这次模型依然是从hungging face上找的一个,gpt-2 small版本,参数比bert还小,主要是gpt-2没有token-type那个2*768的矩阵和一个pooler矩阵,别的都有

gpt-2的模型结构和bert类似,只不过multi-headed-self-attention换成了mask-multi-headed-self-attention,另外

layer_normalization层放到了attention层之前和feedforword层之前
 
最重点的是,我的代码实现了gpt-2推理加速,以前的gpt-2的工程里经常是生成一个新的token后和原来的token序列拼接起来,再给模型输入,这会使模型大大增加计算量,同时mask失去了它的意义,每次都会把之前的token重新推理一边,浪费时间,我的代码中已经实现使用生成的token作为模型输入去推理后面的结果,计算量大大减少,速度大大提升,试想一下向量做矩阵乘法和矩阵做矩阵乘法的差异,同样生成100个token,在cpu上的加速效果快了一倍,如果token长度更长,则加速效果会更明显
 
上numpy代码
  1. import numpy as np
  2. import time
  3.  
  4. def top_k_sampling(probs, k):
  5. # 使用argsort对概率分布数组进行排序,得到索引数组
  6. sorted_indices = np.argsort(probs)[::-1]
  7. # 选择前K个概率最高的词的索引
  8. topk_indices = sorted_indices[:k]
  9. # 根据选择的Top-K索引进行进一步处理,例如按概率重新归一化或随机采样
  10. return topk_indices
  11.  
  12. def random_sampling(array, k):
  13. sample = np.random.choice(array, size=k, replace=False)
  14. return sample
  15.  
  16. def word_embedding(input_ids, word_embeddings):
  17. return word_embeddings[input_ids]
  18.  
  19. def position_embedding(position_ids, position_embeddings):
  20. return position_embeddings[position_ids]
  21.  
  22. def token_type_embedding(token_type_ids, token_type_embeddings):
  23. return token_type_embeddings[token_type_ids]
  24.  
  25. def softmax(x, axis=None):
  26. # e_x = np.exp(x).astype(np.float32) #
  27. e_x = np.exp(x - np.max(x, axis=axis, keepdims=True))
  28. sum_ex = np.sum(e_x, axis=axis,keepdims=True).astype(np.float32)
  29. return e_x / sum_ex
  30.  
  31. def scaled_dot_product_attention(Q, K, V, mask=None):
  32.  
  33. d_k = Q.shape[-1]
  34. attention_scores = np.matmul(Q, K.transpose(0, 2, 1)) / np.sqrt(d_k) #一致
  35. if mask is not None:
  36. # min_value = scores.min()
  37. min_value = np.finfo(attention_scores.dtype).min #找的scores.dtype 这个类型数据的最小值
  38. # scores = np.where(mask, scores, np.full_like(scores, -np.inf))
  39. scores = np.where(mask, attention_scores, np.full_like(attention_scores, min_value)) # 用最小值替换0的部分
  40.  
  41. attention_weights = softmax(scores, axis=-1) # 这样softmax的权重在本来是0的地方得到的数值是0
  42.  
  43. output = np.matmul(attention_weights, V) #一致了
  44. return output, attention_weights
  45.  
  46. def scaled_dot_product_attention2(Q, K, V): # 单部推理 降低计算量
  47.  
  48. global att_scores
  49. d_k = Q.shape[-1]
  50. attention_scores = np.matmul(Q, K.transpose(0, 2, 1)) / np.sqrt(d_k) #一致
  51. attention_weights = softmax(attention_scores, axis=-1) # 这样softmax的权重在本来是0的地方得到的数值是0
  52. output = np.matmul(attention_weights, V) #一致了
  53. return output, attention_weights
  54.  
  55. global_q = {}
  56. global_k = {}
  57. global_v = {}
  58. def mask_multihead_attention(i,input, num_heads,W_Q,B_Q,W_K,B_K,W_V,B_V,W_O,B_O):
  59.  
  60. global global_q,global_k,global_v
  61. q = np.matmul(input, W_Q)+B_Q
  62. k = np.matmul(input, W_K)+B_K
  63. v = np.matmul(input, W_V)+B_V
  64.  
  65. if q.shape[-2] == 1:
  66. k = global_k[i] = np.concatenate([global_k[i],k],axis=-2)
  67. v = global_v[i] = np.concatenate([global_v[i],v],axis=-2)
  68. else:
  69. global_q[i] = q
  70. global_k[i] = k
  71. global_v[i] = v
  72.  
  73. _,n,_ = k.shape
  74. # 分割输入为多个头
  75. q = np.split(q, num_heads, axis=-1)
  76. k = np.split(k, num_heads, axis=-1)
  77. v = np.split(v, num_heads, axis=-1) #到这里都是一致的
  78.  
  79. outputs = []
  80. if q[0].shape[-2] != 1:
  81. mask = np.tril(np.ones((n, n))) #下三角矩阵
  82. for q_,k_,v_ in zip(q,k,v):
  83. output, attention_weights = scaled_dot_product_attention(q_, k_, v_,mask) #一致
  84. outputs.append(output)
  85. else:
  86. for q_,k_,v_ in zip(q,k,v):
  87. output, attention_weights = scaled_dot_product_attention2(q_, k_, v_) #一致
  88. outputs.append(output)
  89.  
  90. outputs = np.concatenate(outputs, axis=-1)
  91. outputs = np.matmul(outputs, W_O)+B_O
  92. return outputs #一致
  93.  
  94. def layer_normalization(x, weight, bias, eps=1e-12):
  95. mean = np.mean(x, axis=-1, keepdims=True)
  96. variance = np.var(x, axis=-1, keepdims=True)
  97. std = np.sqrt(variance + eps)
  98. normalized_x = (x - mean) / std
  99. output = weight * normalized_x + bias
  100. return output
  101.  
  102. def feed_forward_layer(inputs, weight, bias=None, activation='relu'):
  103. if bias is not None:
  104. linear_output = np.matmul(inputs,weight) + bias
  105. else:
  106. linear_output = np.matmul(inputs,weight)
  107.  
  108. if activation == 'relu':
  109. activated_output = np.maximum(0, linear_output) # ReLU激活函数
  110. elif activation == 'gelu':
  111. activated_output = 0.5 * linear_output * (1 + np.tanh(np.sqrt(2 / np.pi) * (linear_output + 0.044715 * np.power(linear_output, 3)))) # GELU激活函数
  112.  
  113. elif activation == "tanh" :
  114. activated_output = np.tanh(linear_output)
  115. else:
  116. activated_output = linear_output # 无激活函数
  117.  
  118. return activated_output
  119.  
  120. def residual_connection(inputs, residual):
  121. # 残差连接
  122. residual_output = inputs + residual
  123. return residual_output
  124.  
  125. with open('vocab.txt', 'r', encoding='utf-8') as f:
  126. vocab = f.readlines()
  127. vocab = [i.strip() for i in vocab]
  128. # print(len(vocab))
  129.  
  130. def tokenize_sentence(sentence):
  131. tokenized_sentence = list(sentence) # 在句子开头添加[cls]
  132. token_ids = [vocab.index(token) for token in tokenized_sentence]
  133.  
  134. return token_ids
  135.  
  136. # 加载保存的模型数据
  137. model_data = np.load('gpt2_model_params.npz')
  138. # for i in model_data:
  139. # # print(i)
  140. # print(i,model_data[i].shape)
  141.  
  142. def get_sentence_ids(sentence):
  143. token_ids = tokenize_sentence(sentence)
  144. input_ids = np.array(token_ids) # 输入的词汇id
  145. return input_ids
  146.  
  147. word_embeddings = model_data["transformer.wte.weight"]
  148. position_embeddings = model_data["transformer.wpe.weight"]
  149. def model_input(input_ids,position_ids):
  150.  
  151. word_embedded = word_embedding(input_ids, word_embeddings)
  152.  
  153. position_ids = np.array(position_ids) # 位置id
  154. # 位置嵌入矩阵,形状为 (max_position, embedding_size)
  155. position_embedded = position_embedding(position_ids, position_embeddings)
  156.  
  157. embedding_output = np.expand_dims(word_embedded + position_embedded, axis=0)
  158. return embedding_output
  159.  
  160. def gpt2(input,num_heads):
  161.  
  162. for i in range(12):
  163.  
  164. LayerNorm1_weight = model_data['transformer.h.{}.ln_1.weight'.format(i)]
  165. LayerNorm1_bias = model_data['transformer.h.{}.ln_1.bias'.format(i)]
  166. # 调用多头自注意力函数
  167. W_QKV = model_data['transformer.h.{}.attn.c_attn.weight'.format(i)]
  168. B_QKV = model_data['transformer.h.{}.attn.c_attn.bias'.format(i)]
  169. W_O = model_data['transformer.h.{}.attn.c_proj.weight'.format(i)]
  170. B_O = model_data['transformer.h.{}.attn.c_proj.bias'.format(i)]
  171.  
  172. LayerNorm2_weight = model_data['transformer.h.{}.ln_2.weight'.format(i)]
  173. LayerNorm2_bias = model_data['transformer.h.{}.ln_2.bias'.format(i)]
  174.  
  175. intermediate_weight = model_data['transformer.h.{}.mlp.c_fc.weight'.format(i)]
  176. intermediate_bias = model_data['transformer.h.{}.mlp.c_fc.bias'.format(i)]
  177. dense_weight = model_data['transformer.h.{}.mlp.c_proj.weight'.format(i)]
  178. dense_bias = model_data['transformer.h.{}.mlp.c_proj.bias'.format(i)]
  179.  
  180. input1 = layer_normalization(input,LayerNorm1_weight,LayerNorm1_bias) #这里和模型输出一致
  181. W_Q,W_K,W_V = np.split(W_QKV, 3, axis=-1)
  182. B_Q,B_K,B_V = np.split(B_QKV, 3, axis=-1)
  183. output = mask_multihead_attention(i,input1, num_heads,W_Q,B_Q,W_K,B_K,W_V,B_V,W_O,B_O) #一致
  184. output1 = residual_connection(input,output) #一致
  185.  
  186. output = layer_normalization(output1,LayerNorm2_weight,LayerNorm2_bias) #一致
  187. output = feed_forward_layer(output, intermediate_weight, intermediate_bias, activation='gelu')
  188. output = feed_forward_layer(output, dense_weight, dense_bias, activation='') #一致
  189. output2 = residual_connection(output1,output)
  190.  
  191. input = output2
  192.  
  193. ln_f_weight = model_data['transformer.ln_f.weight']
  194. ln_f_bias = model_data['transformer.ln_f.bias']
  195. output = layer_normalization(output2,ln_f_weight,ln_f_bias)
  196.  
  197. return output
  198.  
  199. classifier_weight = model_data['lm_head.weight']
  200. def predict(sentence="今天是个好日子",accelerater=True,gen_len=100):
  201.  
  202. start = time.time()
  203. sentence_ids = get_sentence_ids(sentence)
  204. position_ids = range(len(sentence_ids))
  205. print("prompt输入:",sentence)
  206. for i in range(gen_len):
  207. embeddings = model_input(sentence_ids,position_ids)
  208. output = gpt2(embeddings,num_heads=12)
  209. # print(output)
  210. output = feed_forward_layer(output[:,-1], classifier_weight.T, activation='')
  211.  
  212. samples = top_k_sampling(output[0],k=1)
  213.  
  214. label_id = random_sampling(samples,k=1)
  215.  
  216. print(vocab[label_id[0]],end="")
  217.  
  218. if accelerater: #是否使用加速推理减少计算量
  219. sentence_ids = label_id #每次使用上一步的q,和全量的key和v做计算,比使用所有历史时间部的q计算量小很多,所以可以加速
  220. position_ids = [position_ids[-1]+1]
  221. else:
  222. sentence_ids = np.concatenate([sentence_ids,label_id],axis=-1) #慢推理,每次都需要从头计算,计算量会越来越大
  223. position_ids = range(len(sentence_ids))
  224.  
  225. end = time.time()
  226.  
  227. print("\nspend time:",end-start)
  228.  
  229. if __name__ == "__main__":
  230.  
  231. accelerater = False
  232. sentence = "今天是个好日子" #我们要做的就是把握住这个机会
  233.  
  234. predict(sentence,accelerater)
  235.  
  236. # embeddings = model_input(sentence_ids)
  237. # output = gpt2(embeddings,num_heads=12)
  238. # # print(output)
  239. # output = feed_forward_layer(output[:,:], classifier_weight.T, activation='')
  240.  
  241. # samples = np.argmax(output,axis=-1)
  242.  
  243. # for i in samples[0]:
  244. # print(vocab[i],end="")

结果:同样的结果,序列长度越长,时间上的差异越明显,这才生成100tokens,就已经明显看出速度的差异了

  1. 使用加速:
  2. prompt输入: 今天是个好日子
  3. ,我们要做的就是把握住这个机会,把握住这个机会,把握住了,我相信我们的投资将会创造奇迹,而且我相信我们的投资团队一定能够创造奇迹,我相信我们的投资团队一定能够创造奇迹,我相信我们的投资团队一定能够创造
  4. spend time: 22.19951105117798
  5.  
  6. 不使用加速:
  7. prompt输入: 今天是个好日子
  8. ,我们要做的就是把握住这个机会,把握住这个机会,把握住了,我相信我们的投资将会创造奇迹,而且我相信我们的投资团队一定能够创造奇迹,我相信我们的投资团队一定能够创造奇迹,我相信我们的投资团队一定能够创造
  9. spend time: 42.4955039024353

模型参数:

  1. transformer.wte.weight (21128, 768)
  2. transformer.wpe.weight (1024, 768)
  3. transformer.h.0.ln_1.weight (768,)
  4. transformer.h.0.ln_1.bias (768,)
  5. transformer.h.0.attn.c_attn.weight (768, 2304)
  6. transformer.h.0.attn.c_attn.bias (2304,)
  7. transformer.h.0.attn.c_proj.weight (768, 768)
  8. transformer.h.0.attn.c_proj.bias (768,)
  9. transformer.h.0.ln_2.weight (768,)
  10. transformer.h.0.ln_2.bias (768,)
  11. transformer.h.0.mlp.c_fc.weight (768, 3072)
  12. transformer.h.0.mlp.c_fc.bias (3072,)
  13. transformer.h.0.mlp.c_proj.weight (3072, 768)
  14. transformer.h.0.mlp.c_proj.bias (768,)
  15. transformer.h.1.ln_1.weight (768,)
  16. transformer.h.1.ln_1.bias (768,)
  17. transformer.h.1.attn.c_attn.weight (768, 2304)
  18. transformer.h.1.attn.c_attn.bias (2304,)
  19. transformer.h.1.attn.c_proj.weight (768, 768)
  20. transformer.h.1.attn.c_proj.bias (768,)
  21. transformer.h.1.ln_2.weight (768,)
  22. transformer.h.1.ln_2.bias (768,)
  23. transformer.h.1.mlp.c_fc.weight (768, 3072)
  24. transformer.h.1.mlp.c_fc.bias (3072,)
  25. transformer.h.1.mlp.c_proj.weight (3072, 768)
  26. transformer.h.1.mlp.c_proj.bias (768,)
  27. transformer.h.2.ln_1.weight (768,)
  28. transformer.h.2.ln_1.bias (768,)
  29. transformer.h.2.attn.c_attn.weight (768, 2304)
  30. transformer.h.2.attn.c_attn.bias (2304,)
  31. transformer.h.2.attn.c_proj.weight (768, 768)
  32. transformer.h.2.attn.c_proj.bias (768,)
  33. transformer.h.2.ln_2.weight (768,)
  34. transformer.h.2.ln_2.bias (768,)
  35. transformer.h.2.mlp.c_fc.weight (768, 3072)
  36. transformer.h.2.mlp.c_fc.bias (3072,)
  37. transformer.h.2.mlp.c_proj.weight (3072, 768)
  38. transformer.h.2.mlp.c_proj.bias (768,)
  39. transformer.h.3.ln_1.weight (768,)
  40. transformer.h.3.ln_1.bias (768,)
  41. transformer.h.3.attn.c_attn.weight (768, 2304)
  42. transformer.h.3.attn.c_attn.bias (2304,)
  43. transformer.h.3.attn.c_proj.weight (768, 768)
  44. transformer.h.3.attn.c_proj.bias (768,)
  45. transformer.h.3.ln_2.weight (768,)
  46. transformer.h.3.ln_2.bias (768,)
  47. transformer.h.3.mlp.c_fc.weight (768, 3072)
  48. transformer.h.3.mlp.c_fc.bias (3072,)
  49. transformer.h.3.mlp.c_proj.weight (3072, 768)
  50. transformer.h.3.mlp.c_proj.bias (768,)
  51. transformer.h.4.ln_1.weight (768,)
  52. transformer.h.4.ln_1.bias (768,)
  53. transformer.h.4.attn.c_attn.weight (768, 2304)
  54. transformer.h.4.attn.c_attn.bias (2304,)
  55. transformer.h.4.attn.c_proj.weight (768, 768)
  56. transformer.h.4.attn.c_proj.bias (768,)
  57. transformer.h.4.ln_2.weight (768,)
  58. transformer.h.4.ln_2.bias (768,)
  59. transformer.h.4.mlp.c_fc.weight (768, 3072)
  60. transformer.h.4.mlp.c_fc.bias (3072,)
  61. transformer.h.4.mlp.c_proj.weight (3072, 768)
  62. transformer.h.4.mlp.c_proj.bias (768,)
  63. transformer.h.5.ln_1.weight (768,)
  64. transformer.h.5.ln_1.bias (768,)
  65. transformer.h.5.attn.c_attn.weight (768, 2304)
  66. transformer.h.5.attn.c_attn.bias (2304,)
  67. transformer.h.5.attn.c_proj.weight (768, 768)
  68. transformer.h.5.attn.c_proj.bias (768,)
  69. transformer.h.5.ln_2.weight (768,)
  70. transformer.h.5.ln_2.bias (768,)
  71. transformer.h.5.mlp.c_fc.weight (768, 3072)
  72. transformer.h.5.mlp.c_fc.bias (3072,)
  73. transformer.h.5.mlp.c_proj.weight (3072, 768)
  74. transformer.h.5.mlp.c_proj.bias (768,)
  75. transformer.h.6.ln_1.weight (768,)
  76. transformer.h.6.ln_1.bias (768,)
  77. transformer.h.6.attn.c_attn.weight (768, 2304)
  78. transformer.h.6.attn.c_attn.bias (2304,)
  79. transformer.h.6.attn.c_proj.weight (768, 768)
  80. transformer.h.6.attn.c_proj.bias (768,)
  81. transformer.h.6.ln_2.weight (768,)
  82. transformer.h.6.ln_2.bias (768,)
  83. transformer.h.6.mlp.c_fc.weight (768, 3072)
  84. transformer.h.6.mlp.c_fc.bias (3072,)
  85. transformer.h.6.mlp.c_proj.weight (3072, 768)
  86. transformer.h.6.mlp.c_proj.bias (768,)
  87. transformer.h.7.ln_1.weight (768,)
  88. transformer.h.7.ln_1.bias (768,)
  89. transformer.h.7.attn.c_attn.weight (768, 2304)
  90. transformer.h.7.attn.c_attn.bias (2304,)
  91. transformer.h.7.attn.c_proj.weight (768, 768)
  92. transformer.h.7.attn.c_proj.bias (768,)
  93. transformer.h.7.ln_2.weight (768,)
  94. transformer.h.7.ln_2.bias (768,)
  95. transformer.h.7.mlp.c_fc.weight (768, 3072)
  96. transformer.h.7.mlp.c_fc.bias (3072,)
  97. transformer.h.7.mlp.c_proj.weight (3072, 768)
  98. transformer.h.7.mlp.c_proj.bias (768,)
  99. transformer.h.8.ln_1.weight (768,)
  100. transformer.h.8.ln_1.bias (768,)
  101. transformer.h.8.attn.c_attn.weight (768, 2304)
  102. transformer.h.8.attn.c_attn.bias (2304,)
  103. transformer.h.8.attn.c_proj.weight (768, 768)
  104. transformer.h.8.attn.c_proj.bias (768,)
  105. transformer.h.8.ln_2.weight (768,)
  106. transformer.h.8.ln_2.bias (768,)
  107. transformer.h.8.mlp.c_fc.weight (768, 3072)
  108. transformer.h.8.mlp.c_fc.bias (3072,)
  109. transformer.h.8.mlp.c_proj.weight (3072, 768)
  110. transformer.h.8.mlp.c_proj.bias (768,)
  111. transformer.h.9.ln_1.weight (768,)
  112. transformer.h.9.ln_1.bias (768,)
  113. transformer.h.9.attn.c_attn.weight (768, 2304)
  114. transformer.h.9.attn.c_attn.bias (2304,)
  115. transformer.h.9.attn.c_proj.weight (768, 768)
  116. transformer.h.9.attn.c_proj.bias (768,)
  117. transformer.h.9.ln_2.weight (768,)
  118. transformer.h.9.ln_2.bias (768,)
  119. transformer.h.9.mlp.c_fc.weight (768, 3072)
  120. transformer.h.9.mlp.c_fc.bias (3072,)
  121. transformer.h.9.mlp.c_proj.weight (3072, 768)
  122. transformer.h.9.mlp.c_proj.bias (768,)
  123. transformer.h.10.ln_1.weight (768,)
  124. transformer.h.10.ln_1.bias (768,)
  125. transformer.h.10.attn.c_attn.weight (768, 2304)
  126. transformer.h.10.attn.c_attn.bias (2304,)
  127. transformer.h.10.attn.c_proj.weight (768, 768)
  128. transformer.h.10.attn.c_proj.bias (768,)
  129. transformer.h.10.ln_2.weight (768,)
  130. transformer.h.10.ln_2.bias (768,)
  131. transformer.h.10.mlp.c_fc.weight (768, 3072)
  132. transformer.h.10.mlp.c_fc.bias (3072,)
  133. transformer.h.10.mlp.c_proj.weight (3072, 768)
  134. transformer.h.10.mlp.c_proj.bias (768,)
  135. transformer.h.11.ln_1.weight (768,)
  136. transformer.h.11.ln_1.bias (768,)
  137. transformer.h.11.attn.c_attn.weight (768, 2304)
  138. transformer.h.11.attn.c_attn.bias (2304,)
  139. transformer.h.11.attn.c_proj.weight (768, 768)
  140. transformer.h.11.attn.c_proj.bias (768,)
  141. transformer.h.11.ln_2.weight (768,)
  142. transformer.h.11.ln_2.bias (768,)
  143. transformer.h.11.mlp.c_fc.weight (768, 3072)
  144. transformer.h.11.mlp.c_fc.bias (3072,)
  145. transformer.h.11.mlp.c_proj.weight (3072, 768)
  146. transformer.h.11.mlp.c_proj.bias (768,)
  147. transformer.ln_f.weight (768,)
  148. transformer.ln_f.bias (768,)
  149. lm_head.weight (21128, 768)

原始的hunggingface模型,保存模型参数为numpy,然后上面的numpy版的gpt-2就可以加载了

  1. import numpy as np
  2.  
  3. from transformers import BertTokenizer, GPT2LMHeadModel, TextGenerationPipeline
  4. tokenizer = BertTokenizer.from_pretrained("uer/gpt2-chinese-cluecorpussmall")
  5. model = GPT2LMHeadModel.from_pretrained("uer/gpt2-chinese-cluecorpussmall")
  6. text_generator = TextGenerationPipeline(model, tokenizer)
  7. print(text_generator("今天是个好日子", max_length=20, do_sample=True))
  8.  
  9. print(model)
  10.  
  11. # 打印BERT模型的权重维度
  12. # for name, param in model.named_parameters():
  13. # print(name, param.data.shape)
  14.  
  15. # print(model.lm_head.weight)
  16. # print(model.lm_head.bias)
  17.  
  18. # # # 保存模型参数为NumPy格式
  19. model_params = {name: param.data.cpu().numpy() for name, param in model.named_parameters()}
  20. model_params["lm_head.weight"] = model.lm_head.weight.data.cpu().numpy()
  21. np.savez('gpt2_model_params.npz', **model_params)
  22. # model_params

我用numpy实现了GPT-2,GPT-2源码,GPT-2模型加速推理,并且可以在树莓派上运行,读了不少hungging face源码,手动实现了numpy的GPT2模型的更多相关文章

  1. 手把手教你玩转SOCKET模型之重叠I/O篇(上)

    “身为一个初学者,时常能体味到初学者入门的艰辛,所以总是想抽空作点什么来尽我所能的帮助那些需要帮助的人.我也希望大家能把自己的所学和他人一起分享,不要去鄙视别人索取时的贪婪,因为最应该被鄙视的是不肯付 ...

  2. 有关python numpy pandas scipy 等 能在YARN集群上 运行PySpark

    有关这个问题,似乎这个在某些时候,用python写好,且spark没有响应的算法支持, 能否能在YARN集群上 运行PySpark方式, 将python分析程序提交上去? Spark Applicat ...

  3. ZBrush中如何把模型的细节映射到低模上

    我们在ZBrush®雕刻模型的时候,发现模型布线不利于雕刻,这使我们不得不对模型进行重建细分,而重建细分之后的模型细节已经没有了,这个时候我们就需要把原来高模的细节映射到新的模型上面. 接下来我们介绍 ...

  4. StartDT AI Lab | 视觉智能引擎之算法模型加速

    通过StartDT AI Lab专栏之前多篇文章叙述,相信大家已经对计算机视觉技术及人工智能算法在奇点云AIOT战略中的支撑作用有了很好的理解.同样,这种业务牵引,技术覆盖的模式也收获了市场的良好反响 ...

  5. 【实战】yolov8 tensorrt模型加速部署

    [实战]yolov8 tensorrt模型加速部署 TensorRT-Alpha基于tensorrt+cuda c++实现模型end2end的gpu加速,支持win10.linux,在2023年已经更 ...

  6. Windows10下yolov8 tensorrt模型加速部署【实战】

    Windows10下yolov8 tensorrt模型加速部署[实战] TensorRT-Alpha基于tensorrt+cuda c++实现模型end2end的gpu加速,支持win10.linux ...

  7. Win10下yolov8 tensorrt模型加速部署【实战】

    Win10下yolov8 tensorrt模型加速部署[实战] TensorRT-Alpha基于tensorrt+cuda c++实现模型end2end的gpu加速,支持win10.linux,在20 ...

  8. 模型加速[tensorflow&tensorrt]

    在tensorflow1.8之后的版本中,tensorflow.contrib部分都有tensorrt的组件,该组件存在的意义在于,你可以读取pb文件,并调用tensorrt的方法进行subgraph ...

  9. {python之IO多路复用} IO模型介绍 阻塞IO(blocking IO) 非阻塞IO(non-blocking IO) 多路复用IO(IO multiplexing) 异步IO(Asynchronous I/O) IO模型比较分析 selectors模块

    python之IO多路复用 阅读目录 一 IO模型介绍 二 阻塞IO(blocking IO) 三 非阻塞IO(non-blocking IO) 四 多路复用IO(IO multiplexing) 五 ...

  10. 理解盒模型——外边距、内边距和边框之间的关系,IE 8以下版本的浏览器中的盒模型有什么不同。

    一个元素盒模型的层次从内到外分别为:内边距.边框和外边距IE8以下浏览器的盒模型中定义的元素的宽高不包括内边距和边框

随机推荐

  1. 【D01】Django中实现带进度条的倒计时功能(简易版)

    首先说明简易版是只有一个 倒计时 和一个 进度条,页面加载后自动开始计时,下次计时需要手动刷新页面. 后续会更新实现完整的倒计时功能的文章 前期准备 前端框架 你需要准备一些前端框架:Bootstra ...

  2. PHP开发者交流群

    PHP开发者交流群 欢迎大家加入学习讨论 QQ群(493834732)

  3. Proxy 与 Object.defineProperty 优劣对比?

    Proxy的优势如下 1.Proxy 可以直接监听对象而不是属性(Object.defineProperty一次只能监视一个属性,如果要监视一个对象,那么需要遍历这个对象),可以直接监听数组的变化(O ...

  4. 深度学习入门系列之doc

    这周老师让把深度学习的名词过一遍,小玛同学准备在过一遍Deep Learning名词的同时把基本的模型也过一遍. 感谢杰哥发我深度学习入门系列能让我有机会快速入门. 下面就来doc一些学到的东西 线性 ...

  5. C语言跳转浏览器打开指定URL

    #include <stdlib.h> int main() { // 定义要打开的URL char* url = "https://rjku.gitee.io/"; ...

  6. 深度相机(TOF)的工作原理

    文章目录 深度相机(TOF)的工作原理 TOF由什么组成? 一.TOF相机采用主动光探测,通常包括以下几个部分: 二.TOF是如何测距的呢? 三.TOF会受什么影响? 四.那TOF相机最后输出的是什么 ...

  7. 刺激!ChatGPT给我虚构了一本书?

    ChatGPT很强大,可以帮我们处理很多问题,但这些问题的答案的正确性您是否有考证过呢? 昨晚,DD就收到了一个有趣的反馈: 提问:有什么关于数据权限设计的资料推荐吗? ChatGPT居然介绍了一本根 ...

  8. 如何实现一个sync.Once

    sync.Once 是 golang里用来实现单例的同步原语.Once 常常用来初始化单例资源, 或者并发访问只需初始化一次的共享资源,或者在测试的时候初始化一次测试资源. 单例,就是某个资源或者对象 ...

  9. Java8 Stream流的合并

    最近的需求里有这样一个场景,要校验一个集合中每个对象的多个Id的有效性.比如一个Customer对象,有3个Id:id1,id2,id3,要把这些Id全部取出来,然后去数据库里查询它是否存在. @Da ...

  10. PCI-5565系列反射内存卡 反射内存交换机

    主要性能:1路发射,一路接收光纤高速网络2.125GHz.最大256个节点.在板128MByte SDRAM.光纤通讯协议不占用CPU资源.动态包长,每个包4 到 64 个字节.33MHz PCI 3 ...