E/tflite (18179): Ошибка регистрации.
I/flutter (18179): Ошибка загрузки модели: Недопустимые аргументы: Невозможно создать интерпретатор.
Код: Выделить всё
packages:
- .
а это файлы в pubsbe.yaml
Код: Выделить всё
assets/gpt2/gpt2_model.tflite
- assets/tokenizer/merges.txt
- assets/tokenizer/special_tokens_map.json
- assets/tokenizer/tokenizer.json
- assets/tokenizer/tokenizer_config.json
- assets/tokenizer/vocab.json
Код: Выделить всё
class _ChatProAiScreenState extends State {
final List _messages = [];
late TextEditingController _inputController;
String _fromLanguage = SharedPrefController.instance.getFromLanguage();
final FlutterTts _flutterTts = FlutterTts();
bool _isListening = false;
SpeechToText _speechToText = SpeechToText();
bool _isSpeechAvailable = false;
double progressValue = 0.0; // Value for progress (elapsed time)
int totalDuration = 59; // Duration of speech in seconds
Timer? _timer; // Timer for progress bar
bool _isRecording = false;
Interpreter? _interpreter; // TensorFlow Lite interpreter
IsolateInterpreter? _isolateInterpreter; // IsolateInterpreter for async inference
Map? _vocab;
List? _merges;
Map? _specialTokens;
Map? _tokenizerConfig; // Config from tokenizer_config.json
late Map _tokenToId;
late Map _idToToken;
bool _isCaseInsensitive = false;
bool _paddingEnabled = false;
int _maxLength = 64;
bool _truncationEnabled = false;
bool _useAttentionMasks = false;
String? _specialPrefixToken;
String? _specialSuffixToken;
bool _addPrefixSpace = false;
double _bpeDropout = 0.0;
bool byteLevel = false;
int? _padToMultipleOf;
int _modelMaxLength = 64;
bool _returnTokenTypeIds = false;
@override
void initState() {
// TODO: implement initState
super.initState();
_inputController = TextEditingController();
_initializeSpeech();
_initializeModel();
_loadModelAndTokenizer();
}
@override
void dispose() {
// TODO: implement dispose
_inputController.dispose();
_speechToText.stop();
_interpreter?.close();
super.dispose();
}
// Initialize TensorFlow Lite Model
Future _initializeModel() async {
try {
_interpreter = await Interpreter.fromAsset(
'assets/gpt2/gpt2_model.tflite'); // Load TFLite model
if (_interpreter != null) {
_isolateInterpreter = await IsolateInterpreter.create(address: _interpreter!.address); // Wrap interpreter
print('Model initialized successfully');
} else {
throw Exception('Interpreter could not be initialized');
}
} catch (e) {
print('Error loading model: $e');
}
}
// Load tokenizer data (vocab, merges, and special tokens)
Future _loadModelAndTokenizer() async {
try {
// Load vocab.json
String vocabJson = await rootBundle.loadString('assets/tokenizer/vocab.json');
_vocab = jsonDecode(vocabJson);
// Load merges.txt
String mergesTxt = await rootBundle.loadString('assets/tokenizer/merges.txt');
_merges = mergesTxt.split('\n');
// Load special_tokens_map.json
String specialTokensMapJson = await rootBundle.loadString('assets/tokenizer/special_tokens_map.json');
_specialTokens = jsonDecode(specialTokensMapJson);
// Load tokenizer.json for additional token mappings
String tokenizerJson = await rootBundle.loadString('assets/tokenizer/tokenizer.json');
Map tokenizerData = jsonDecode(tokenizerJson);
_addAdditionalTokenMappings(tokenizerData);
// Load tokenizer_config.json to apply specific settings
String tokenizerConfigJson = await rootBundle.loadString('assets/tokenizer/tokenizer_config.json');
_tokenizerConfig = jsonDecode(tokenizerConfigJson);
_applyConfigSettings();
// Map vocab to token IDs
_tokenToId = _vocab!.map((key, value) => MapEntry(key, value as int));
_idToToken = _tokenToId.map((key, value) => MapEntry(value, key));
// Incorporate special tokens into vocab if needed
if (_specialTokens != null) {
_specialTokens!.forEach((key, value) {
if (!_tokenToId.containsKey(key)) {
_tokenToId[key] = value as int;
_idToToken[value as int] = key;
}
});
}
print('Tokenizer loaded successfully');
} catch (e) {
print('Error loading tokenizer: $e');
}
}
// Function to apply BPE rules for subword tokenization
List applyBPE(String word) {
if (_merges == null || _merges!.isEmpty) return [word];
// Tokenize the word into characters (initial BPE step)
List tokens = word.split('');
while (true) {
String bestPair;
int bestPairIndex = -1;
// Look for the best pair to merge based on the _merges rules
for (var i = 0; i < tokens.length - 1; i++) {
String pair = tokens[i] + ' ' + tokens[i + 1];
// if (_merges!.contains([tokens[i], tokens[i + 1]]) && (bestPairIndex == -1 || _merges!.indexOf([tokens[i], tokens[i + 1]]) < bestPairIndex)) {
if (_merges!.contains(pair) && (bestPairIndex == -1 || _merges!.indexOf(pair) < bestPairIndex)) {
bestPair = pair;
bestPairIndex = i;
}
}
if (bestPairIndex == -1) {
// No more merges can be applied, break out of the loop
break;
}
// Merge the best pair
tokens[bestPairIndex] = tokens[bestPairIndex] + tokens[bestPairIndex + 1];
tokens.removeAt(bestPairIndex + 1);
}
return tokens;
}
// Function to add additional token mappings from tokenizer.json
void _addAdditionalTokenMappings(Map tokenizerData) {
if (tokenizerData.containsKey('model')) {
var tokenMap = tokenizerData['model']['vocab'] as Map;
tokenMap.forEach((token, id) {
if (!_tokenToId.containsKey(token)) {
_tokenToId[token] = id as int;
_idToToken[id as int] = token;
}
});
}
}
// Function to apply configurations from tokenizer_config.json
void _applyConfigSettings() {
if (_tokenizerConfig == null) return;
// 1. Apply case-insensitivity if configured
if (_tokenizerConfig!.containsKey('do_lower_case') && _tokenizerConfig!['do_lower_case']) {
_isCaseInsensitive = true;
} else {
_isCaseInsensitive = false;
}
// 2. Handle padding if padding is specified in the config
if (_tokenizerConfig!.containsKey('padding') && _tokenizerConfig!['padding'] == 'max_length') {
_paddingEnabled = true; // Add class member to control padding
if (_tokenizerConfig!.containsKey('max_length')) {
_maxLength = _tokenizerConfig!['max_length']; // Set the max length for padding
print('Padding enabled with max length: $_maxLength');
} else {
_maxLength = 64; // Set default max length if not provided
print('Padding enabled with default max length: $_maxLength');
}
} else {
_paddingEnabled = false;
}
// 2.1 Handle padding to multiple of a specific value
if (_tokenizerConfig!.containsKey('pad_to_multiple_of')) {
var padValue = _tokenizerConfig!['pad_to_multiple_of'];
if (padValue is int && padValue > 0) {
_padToMultipleOf = padValue;
print('Padding to multiple of: $_padToMultipleOf');
} else {
print('Invalid pad_to_multiple_of, skipping.');
}
}
// 3. Handle truncation if configured
if (_tokenizerConfig!.containsKey('truncation') && _tokenizerConfig!['truncation']) {
_truncationEnabled = true; // Track truncation setting
print('Truncation is enabled.');
} else {
_truncationEnabled = false;
}
// 3.1 Handle maximum model length if provided (model_max_length)
if (_tokenizerConfig!.containsKey('model_max_length')) {
_modelMaxLength = _tokenizerConfig!['model_max_length'];
print('Model max length: $_modelMaxLength');
}
// 4. Handle special tokens if defined in the config
if (_tokenizerConfig!.containsKey('special_tokens')) {
var specialTokens = _tokenizerConfig!['special_tokens'] as Map;
_applySpecialTokens(specialTokens);
print('Special tokens applied: $specialTokens');
}
// 5. Apply prefix and suffix tokens if configured correctly
if (_tokenizerConfig!.containsKey('prefix_token')) {
_specialPrefixToken = _tokenizerConfig!['prefix_token'];
_addPrefixSpace = _tokenizerConfig!.containsKey('add_prefix_space') && _tokenizerConfig!['add_prefix_space'];
}
if (_tokenizerConfig!.containsKey('suffix_token')) {
_specialSuffixToken = _tokenizerConfig!['suffix_token'];
}
// 6. Byte-level encoding (for GPT models)
if (_tokenizerConfig!.containsKey('byte_level') && _tokenizerConfig!['byte_level']) {
_applyByteLevelEncoding();
}
// 7. Stride (for overlapping tokens)
if (_tokenizerConfig!.containsKey('stride')) {
int stride = _tokenizerConfig!['stride'];
print('Stride for overlapping tokens: $stride');
}
// 8. Attention masks
_useAttentionMasks = _tokenizerConfig!.containsKey('use_attention_masks') && _tokenizerConfig!['use_attention_masks'] ?? false;
// 9. Handle BPE dropout if configured (optional for some models)
_bpeDropout = _tokenizerConfig!.containsKey('bpe_dropout') && _tokenizerConfig!['bpe_dropout'] > 0
? _tokenizerConfig!['bpe_dropout']
: 0.0;
// 10. Return token type IDs (needed for models like BERT)
_returnTokenTypeIds = _tokenizerConfig!.containsKey('return_token_type_ids') && _tokenizerConfig!['return_token_type_ids'];
print('Return token type IDs: $_returnTokenTypeIds');
// Add any additional config options if required
}
// Helper function to apply special tokens
void _applySpecialTokens(Map specialTokens) {
specialTokens.forEach((key, value) {
_specialTokens![key] = value as int;
});
}
// Send message function
void _handleSendPressed(String messageText) async {
if (messageText.trim().isNotEmpty) {
setState(() {
_messages.add({
'message': messageText,
'isUser': true,
});
});
_inputController.clear();
String botResponse = await _generateResponse(messageText);
setState(() {
_messages.add({
'message': botResponse,
'isUser': false,
});
});
} else {
print('Error: Message text is empty');
}
}
// Generate response using TFLite model (async with IsolateInterpreter)
Future _generateResponse(String inputText) async {
if (_isolateInterpreter == null) return 'Model not initialized';
// Tokenize input text (now returns a map)
Map tokenizedInput = _tokenizeInput(inputText);
List inputTokenIds = tokenizedInput['input_ids'];
List attentionMasks = tokenizedInput['attention_masks'];
// Prepare input tensor
final inputTensor = _prepareInputTensor(inputTokenIds);
// Prepare attention masks tensor if needed (if attention masks are used in the model)
final attentionMaskTensor = _prepareInputTensor(attentionMasks);
// Prepare output tensor
List outputTokenIds = List.filled(64, 0); // Assuming max length of 64 tokens for output
// Asynchronous inference with IsolateInterpreter
try {
await _isolateInterpreter?.run([inputTensor, attentionMaskTensor], outputTokenIds);
} catch (e) {
print('Error during model inference: $e');
return 'Error generating response';
}
// Decode the output
return _decodeOutput(outputTokenIds);
}
// Prepare input tensor for TFLite model
Uint8List _prepareInputTensor(List inputTokenIds) {
// Convert List to Uint8List for TFLite
return Uint8List.fromList(inputTokenIds);
}
// Tokenize input string into token IDs
Map _tokenizeInput(String input) {
List tokenIds = [];
// 1. Apply case insensitivity if configured
if (_isCaseInsensitive) {
input = input.toLowerCase();
}
// 2. Tokenize input (split into words or byte-level encoding)
List tokens = byteLevel ? _byteTokenize(input) : input.split(' ');
// 3. Add prefix token if available
if (_specialPrefixToken != null) {
if (_addPrefixSpace) tokens.insert(0, ' ');
tokens.insert(0, _specialPrefixToken!);
}
for (String token in tokens) {
// 4. Apply BPE rules to tokenize the word into subwords
List subwordTokens = applyBPE(token);
// Convert subword tokens to token IDs
for (String subwordToken in subwordTokens) {
if (_tokenToId.containsKey(subwordToken)) {
tokenIds.add(_tokenToId[subwordToken]!);
} else if (_specialTokens != null && _specialTokens!.containsKey(subwordToken)) {
tokenIds.add(_specialTokens![subwordToken]!); // Handle special tokens
} else {
tokenIds.add(_tokenToId['']!); // Handle unknown tokens
}
}
}
// 5. Optionally add suffix special token
if (_specialSuffixToken != null) {
tokenIds.add(_tokenToId[_specialSuffixToken!]!); // Add suffix token (e.g., )
}
// 6. Apply padding if enabled
if (_paddingEnabled && tokenIds.length < _maxLength) {
int padCount = _maxLength - tokenIds.length;
tokenIds.addAll(List.filled(padCount, _tokenToId['
']!));
}
// 7. Apply truncation if enabled
if (_truncationEnabled && tokenIds.length > _maxLength) {
tokenIds = tokenIds.sublist(0, _maxLength);
}
// 8. Generate attention masks based on token IDs
List attentionMasks = _generateAttentionMasks(tokenIds);
// Return both token IDs and attention masks as a map
return {
'input_ids': tokenIds,
'attention_masks': attentionMasks,
};
}
// Helper function to generate attention masks
List _generateAttentionMasks(List tokenIds) {
if (!_useAttentionMasks) return [];
// Create an attention mask: 1 for real tokens, 0 for padding
return List.generate(tokenIds.length, (index) => tokenIds[index] == _tokenToId[''] ? 0 : 1);
}
// Byte-level encoding function (for GPT models)
List _byteTokenize(String input) {
return input.runes.map((rune) => String.fromCharCode(rune)).toList();
}
// Function to handle byte-level encoding
void _applyByteLevelEncoding() {
// Ensure the vocabulary and merges are loaded
if (_vocab == null || _merges == null) {
print('Error: Vocabulary or merges not loaded for byte-level encoding.');
return;
}
print('Byte-level tokenization enabled.');
// Iterate through the vocabulary and create byte-level tokens if necessary
for (String token in _vocab!.keys) {
// Break down the token into individual byte representations
List byteRepresentation = _convertToBytes(token);
// Map the byte tokens to the model's vocabulary IDs
for (int byte in byteRepresentation) {
String byteToken = _byteToToken(byte);
if (!_tokenToId.containsKey(byteToken)) {
_tokenToId[byteToken] = byte;
_idToToken[byte] = byteToken;
}
}
}
}
// Helper function to convert a string into its byte representation
List _convertToBytes(String input) {
// Convert each character to its UTF-8 byte value
return input.codeUnits;
}
// Helper function to convert byte values to corresponding token representations
String _byteToToken(int byteValue) {
// Map byte values to corresponding token format, e.g., '' for byte 23
return '';
}
// Decode output token IDs into a string
String _decodeOutput(List tokenIds) {
StringBuffer decodedText = StringBuffer();
for (int id in tokenIds) {
if (_idToToken.containsKey(id)) {
decodedText.write(_idToToken[id]! + ' ');
}
}
return decodedText.toString().trim();
}
Future _initializeSpeech() async {
var status = await Permission.microphone.request();
if (status.isGranted) {
bool available = await _speechToText.initialize(
onStatus: _onSpeechStatus, onError: _onSpeechError);
if (available) {
setState(() {
_isSpeechAvailable = true;
});
} else {
// Handle case where speech recognition is not available
print("Speech recognition not available");
}
} else {
print('Microphone permission denied');
}
}
Код: Выделить всё
from transformers import TFAutoModelForCausalLM, AutoTokenizer
import tensorflow as tf
# Step 1: Load the pre-trained model and tokenizer
model = TFAutoModelForCausalLM.from_pretrained("distilgpt2")
tokenizer = AutoTokenizer.from_pretrained("distilgpt2")
# Step 2: Tokenize input
def tokenize_input(text):
input_ids = tokenizer.encode(text, return_tensors='tf')
return input_ids
# Step 3: Convert model to TensorFlow Lite
converter = tf.lite.TFLiteConverter.from_keras_model(model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
tflite_model = converter.convert()
# Step 4: Save the TensorFlow Lite model
with open('distilgpt2_model.tflite', 'wb') as f:
f.write(tflite_model)
# Step 5: Save the tokenizer
tokenizer.save_pretrained('./tokenizer')
# Function to decode model output
def decode_output(output_ids):
return tokenizer.decode(output_ids, clean_up_tokenization_spaces=True)
Подробнее здесь: https://stackoverflow.com/questions/790 ... lutter-app