import tensorflow as tffrom transformers import TFDistilBertForQuestionAnsweringdistilbert = TFDistilBertForQuestionAnswering.from_pretrained('distilbert-base-cased-distilled-squad')callable = tf.function(distilbert.call)여기서는 Keras 모델 call에서 호출되는 함수를 tf.function으로 전달했습니다. 이때 callable이 반환되며, get_concrete_function 덕분에 특정한 시그니처와 Shape을 가진 호출 함수를 추적하는 데 바로 이 callable을 사용할 수 있습니다.concrete_function = callable.get_concrete_function([tf.TensorSpec([None, 384], tf.int32, name="input_ids"), tf.TensorSpec([None, 384], tf.int32, name="attention_mask")])
tf.saved_model.save(distilbert, 'distilbert_cased_savedmodel', signatures=concrete_function)
saved_model_cli:$ saved_model_cli show --dir distilbert_cased_savedmodel --tag_set serve --signature_def serving_default출력:The given SavedModel SignatureDef contains the following input(s): inputs['attention_mask'] tensor_info: dtype: DT_INT32 shape: (-1, 384) name: serving_default_attention_mask:0 inputs['input_ids'] tensor_info: dtype: DT_INT32 shape: (-1, 384) name: serving_default_input_ids:0The given SavedModel SignatureDef contains the following output(s): outputs['output_0'] tensor_info: dtype: DT_FLOAT shape: (-1, 384) name: StatefulPartitionedCall:0 outputs['output_1'] tensor_info: dtype: DT_FLOAT shape: (-1, 384) name: StatefulPartitionedCall:1Method name is: tensorflow/serving/predict
const model = await tf.node.loadSavedModel(path); // Load the model located in pathconst result = tf.tidy(() => { // ids and attentionMask are of type number[][] const inputTensor = tf.tensor(ids, undefined, "int32"); const maskTensor = tf.tensor(attentionMask, undefined, "int32"); // Run model inference return model.predict({ // “input_ids” and “attention_mask” correspond to the names specified in the signature passed to get_concrete_function during the model conversion “input_ids”: inputTensor, “attention_mask”: maskTensor }) as tf.NamedTensorMap;});// Extract the start and end logits from the tensors returned by model.predictconst [startLogits, endLogits] = await Promise.all([ result[“output_0"].squeeze().array() as Promise, result[“output_1”].squeeze().array() as Promise]);tf.dispose(result); // Clean up memory used by the result tensor since we don’t need it anymore
const tokenizer = await BertWordPieceTokenizer.fromOptions({ vocabFile: vocabPath, lowercase: false});tokenizer.setPadding({ maxLength: 384 }); // 384 matches the shape of the signature input provided while exporting to SavedModel// Here question and context are in their original string formatconst encoding = await tokenizer.encode(question, context);const { ids, attentionMask } = encoding;이것으로 끝입니다! 단 네 줄의 코드로 우리가 이후에 TensorFlow.js로 모델 피드에 사용할 수 있는 형식으로 사용자 입력을 변환할 수 있습니다.
import { QAClient } from "question-answering"; // If using Typescript or Babel// const { QAClient } = require("question-answering"); // If using vanilla JSconst text = ` Super Bowl 50 was an American football game to determine the champion of the National Football League (NFL) for the 2015 season. The American Football Conference (AFC) champion Denver Broncos defeated the National Football Conference (NFC) champion Carolina Panthers 24–10 to earn their third Super Bowl title. The game was played on February 7, 2016, at Levi's Stadium in the San Francisco Bay Area at Santa Clara, California. As this was the 50th Super Bowl, the league emphasized the "golden anniversary" with various gold-themed initiatives, as well as temporarily suspending the tradition of naming each Super Bowl game with Roman numerals (under which the game would have been known as "Super Bowl L"), so that the logo could prominently feature the Arabic numerals 50.`;const question = "Who won the Super Bowl?";const qaClient = await QAClient.fromOptions();const answer = await qaClient.predict(question, text);console.log(answer); // { text: 'Denver Broncos', score: 0.3 }