VMProtect uses a few anti-debug techniques. Firstly, you aren't going to want to tackle them on your own because there is quite and exhaustive set of techniques to detect a debugger. Consider using an anti-anti-debug plugin (ScyllaHide)
One you are probably going to encounter that is difficult to work around is the rdtsc instruction.
rdtsc essentially allows the application to measure time that has elapsed in-between a series of instructions executing. The stepping behavior of a debugger will make this period of time large and thus trigger a detection that a debugger is present via some application logic. With heavy code obfuscation there is no way you can manually work around these. You will need to use find some automated approach (however, since rdtsc is not a privileged instruction getting around this can be a huge pain.)
The best approach here is probably write a custom Intel PIN tool to modify the CPU state as the instruction is used (see https://github.com/jingpu/pintools/blob/master/source/tools/InstLib/time_warp.H ). There are other approaches too (including using a kernel level driver, but IIRC this approach can be very slow and difficult to get working.)
As far as overall the approach you take with VMProtect, the obfuscation is quite complex and if you have never devirtualized code before than you're going to want to try a simple VM first. Devirtualizing code and reverse engineering Virtual Machines, especially ones as obfuscated as VMProtect, can be a project that takes week.
Also VMProtect has multiple different VM "archetypes" per-se. There are some simpler VMs with heavier obfuscation in other areas and some very heavy-weight VMs or multiple layers of vitualization. So it is definitely not a project you want to approach without understanding practical applications of other code obfuscation techniques (control flow flattening, false predicates, and virtualization)